1、Mode成员分工
Source0:
触摸事件处理
performSelector:onThread:
Source1:
基于Port的线程间通信
系统事件捕捉
Timers:
NSTimer
performSelector:withObject:afterDelay:
Observers:
用于监听RunLoop的状态
UI刷新(BeforeWaiting)
Autorelease pool(BeforeWaiting)
2、RunLoop状态
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0),// 进入RunLoop
kCFRunLoopBeforeTimers = (1UL << 1),// 即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2),// 即将处理Source
kCFRunLoopBeforeWaiting = (1UL << 5),// 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6),// 即将结束休眠
kCFRunLoopExit = (1UL << 7), // 退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
可以通过给当前RunLoop添加observer查看各个状态:
// 给RunLoop添加observer
- (void)addRunLoopObserver {
// 创建Observer
CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, observeRunLoopActicities, NULL);
// 添加Observer到RunLoop中
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
// 释放
CFRelease(observer);
}
void observeRunLoopActicities(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
{
switch (activity) {
case kCFRunLoopEntry:
NSLog(@"kCFRunLoopEntry");
break;
case kCFRunLoopBeforeTimers:
NSLog(@"kCFRunLoopBeforeTimers");
break;
case kCFRunLoopBeforeSources:
NSLog(@"kCFRunLoopBeforeSources");
break;
case kCFRunLoopBeforeWaiting:
NSLog(@"kCFRunLoopBeforeWaiting");
break;
case kCFRunLoopAfterWaiting:
NSLog(@"kCFRunLoopAfterWaiting");
break;
case kCFRunLoopExit:
NSLog(@"kCFRunLoopExit");
break;
default:
break;
}
}
*除了使用C语言方法回调,也可以使用block作为回调
3、RunLoop的运行逻辑
3、RunLoop休眠实现原理
当没有事件需要处理时,RunLoop会进入休眠状态,休眠并不是通过while循环阻塞线程,而是调用mach_msg方法,使用内核层面的功能,让线程进入内核态,等有新的事件需要处理时,再返回用户态。