新建 NSThread CFRunLoop

2019-08-20  本文已影响0人  yulekwok
   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);
}
上一篇 下一篇

猜你喜欢

热点阅读