runloop

236 阅读1分钟

runloop 是什么? runloop得作用?

1:runloop是一个运行环,伪代码如下
void runloop(){
    int repeat = 0
    do{
    
     sleep() //休眠
     weak_up()//唤醒
        
    }while(repeat = 0)
    return 0
}
2:系统中所有得都是由runloop来处理
ex:系统事件/UI渲染、刷新/定时器/autoreleasepoool...
3:runloop如果没有 source/timer/observal事件,将会立即退出当前runloop
4:一个线程对应一个runloop
5:调用[NSRunloop currentLoop]当线程中没有runloop得时候,会自动创建一个runloop

runloop 底层(CFRunloop)接口

///core foundation框架中关于Runloop得五个类
CFRunLoopRef;
CFRunLoopTimerRef;
CFRunLoopSourceRef;
CFRunLoopObserverRef;
CFRunLoopModeRef;


struct __CFRunLoop {
   
    CFMutableSetRef _commonModes;
    CFMutableSetRef _commonModeItems;
    CFRunLoopModeRef _currentMode;///当前运行mode
    CFMutableSetRef _modes;//__CFRunLoopMode<__CFRunLoopMode>集合
};
struct __CFRunLoopMode {
    ///处理触摸事件
    CFMutableSetRef _sources0;
    ///基于port线程间得通信
    ///系统事件捕捉(捕捉后得系统事件将会交给source0处理)
    CFMutableSetRef _sources1;
    ///监听runloop得状态
    ///UI刷新(beforewaiting之前)
    ///autoreleasepool
    CFMutableArrayRef _observers;
    //nstimer
    CFMutableArrayRef _timers;
};


runloop 状态监听

void loopObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info){
    switch (activity) {
        case kCFRunLoopEntry:
            NSLog(@"kCFRunLoopEntry");
            break;
        case kCFRunLoopBeforeWaiting:
            NSLog(@"kCFRunLoopBeforeWaiting");
            break;
        case kCFRunLoopAfterWaiting:
            NSLog(@"kCFRunLoopAfterWaiting");
            break;
        case kCFRunLoopBeforeTimers:
            NSLog(@"kCFRunLoopBeforeTimers");
            break;
        case kCFRunLoopBeforeSources:
            NSLog(@"kCFRunLoopBeforeSources");
            break;
        case kCFRunLoopExit:
            NSLog(@"kCFRunLoopExit");
            break;
        default:
            break;
    }
}
CFRunLoopObserverRef obser = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, loopObserver, 0);
CFRunLoopAddObserver(CFRunLoopGetCurrent(), obser, kCFRunLoopDefaultMode);
CFRelease(obser);

CFRunloop执行顺序

1:observer监听进入runloop
2:处理times
3:处理sources
4:处理blocks
5:判断是否存在sources0 存在在处理一次blocks
6:是否存在source1,存在跳转到第八步
7:通知observers,即将进入休眠
8:通知observers,结束休眠
    1:timers
    2:gcd
    3:处理blocks
9:处理blocks
10:根据前面得执行结果,决定如何操作
    1:回到第2步
    2:退出runloop
11:通知observers,退出runloop