NSThread * pthread = [[NSThread alloc] initWithBlock:^{
NSLog(@"begin----");
// 创建上下文(要初始化一下结构体)
CFRunLoopSourceContext context = {0};
// 创建source
CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
// 往Runloop中添加source
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
// 销毁source
CFRelease(source);
// 启动
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
// while (weakSelf && !weakSelf.isStopped) {
// // 第3个参数:returnAfterSourceHandled,设置为true,代表执行完source后就会退出当前loop
// CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, true);
// }
}];
CFRunLoopStop(CFRunLoopGetCurrent());
runLoop 的工作流程
序号 |
说明 |
对应的方法 在命令行bt 可以打印堆栈信息 |
1 |
通知Observers:进入Loop |
CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION |
2 |
通知Observers:即将处理Timers |
|
3 |
通知Observers:即将处理Sources |
|
4 |
处理Blocks |
CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK |
5 |
处理Source0(可能会再次处理Blocks) |
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION |
6 |
如果存在Source1,就跳转到第8步 |
|
7 |
通知Observers:开始休眠(等待消息唤醒) |
|
8 |
通知Observers:结束休眠(被某个消息唤醒) |
|
|
1>处理Timers |
CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION |
|
2>处理GCD Async To Main Queue |
CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE (大部分情况下GCD自己处理 这种情况下才会 dispatch_async(dispatch_get_main_queue(), ^{})) |
|
3>处理Source1 |
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION |
9 |
处理Blocks |
CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK |
10 |
根据前面的执行结果,决定如何操作 |
|
|
1>回到第2步 |
|
|
2>退出Loop |
|
11 |
通知Observers:退出RunLoop |
|
typedef struct __CFRunLoop * CFRunLoopRef;
struct __CFRunLoop {
pthread_t _pthread;
CFMutableSetRef _commonModes;
CFMutableSetRef _commonModeItems;
CFRunLoopModeRef _currentMode;
CFMutableSetRef _modes;
};
typedef struct __CFRunLoopMode *CFRunLoopModeRef;
struct __CFRunLoopMode {
CFStringRef _name;
CFMutableSetRef _sources0;
CFMutableSetRef _sources1;
CFMutableArrayRef _observers;
CFMutableArrayRef _timers;
};
runLoop |
runLoop |
Mode |
Mode |
source0 |
source0 |
source1 |
source1 |
observers |
observers |
timers |
timers |
mode |
Action |
source0 |
1. 触摸事件 2. performSelector:onThread: |
source1 |
1.基于Port的线程间通信 2. 系统事件捕捉 |
Timers |
1.NSTimer 2. performSelector: withObject: afterDelay: |
Observers |
1. 用于监听RunLoop的状态 2. UI刷新(BeforeWating) 3. AutoRelease Pool |
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), // 即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2), // 即将处理Source
kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 即将从休眠中唤醒
kCFRunLoopExit = (1UL << 7), //即将退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
添加监听
void observerRunLoopActivity(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
{
CFRunLoopMode mode = CFRunLoopCopyCurrentMode(CFRunLoopGetCurrent());
NSLog(@"mode == %@", mode);
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;
}
CFRelease(mode);
}
- (void)createObserver1 {
// 创建observer
CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, observerRunLoopActivity, NULL);
// 添加observer 到runloop中
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
// 释放observer
CFRelease(observer);
}
- (void)createObserver2 {
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
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;
}
});
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
CFRelease(observer);
}
网友评论