实际上就是一个do...while循环
xxxxxxxxxxint32_t result;do {CHECK_FOR_FORK();} while ( result);
apple不允许直接创建runloop,只提供两个自动获取的函数:CFRunLoopGetMain()和CFRunLoopGetCurrent()2,线程和runloop是一一对应的,保存在一个全局的NSDictionary里。只能在当前线程中操作当前线程的runloop,不能操作其他线程的runloop
3,runloop在第一次获取的时候创建,在线程结束的时候销毁。
4,内部实现如下:
xxxxxxxxxx/// 全局的Dictionary,key 是 pthread_t, value 是 CFRunLoopRefstatic CFMutableDictionaryRef loopsDic;/// 访问 loopsDic 时的锁static CFSpinLock_t loopsLock;/// 获取一个 pthread 对应的 RunLoop。CFRunLoopRef _CFRunLoopGet(pthread_t thread) {OSSpinLockLock(&loopsLock);if (!loopsDic) {// 第一次进入时,初始化全局Dic,并先为主线程创建一个 RunLoop。loopsDic = CFDictionaryCreateMutable();CFRunLoopRef mainLoop = _CFRunLoopCreate();CFDictionarySetValue(loopsDic, pthread_main_thread_np(), mainLoop);}/// 直接从 Dictionary 里获取。CFRunLoopRef loop = CFDictionaryGetValue(loopsDic, thread));if (!loop) {/// 取不到时,创建一个loop = _CFRunLoopCreate();CFDictionarySetValue(loopsDic, thread, loop);/// 注册一个回调,当线程销毁时,顺便也销毁其对应的 RunLoop。_CFSetTSD(..., thread, loop, __CFFinalizeRunLoop);}OSSpinLockUnLock(&loopsLock);return loop;}CFRunLoopRef CFRunLoopGetMain() {return _CFRunLoopGet(pthread_main_thread_np());}CFRunLoopRef CFRunLoopGetCurrent() {return _CFRunLoopGet(pthread_self());}
CFRunLoopRef:RunLoop对象CFRunLoopModeRef:运行模式CFRunLoopSourceRef:输入源/事件源 source1/source0CFRunLoopTimerRef:定时源CFRunLoopObserverRef:观察者
Source0:非基于Port的。只包含了一个回调(函数指针),它并不能主动触发事件。使用时,你需要先调用CFRunLoopSourceSignal(source),将这个Source 标记为待处理,然后手动调用CFRunLoopWakeUp(runloop)来唤醒RunLoop,让其处理这个事件。比如UIView的刷新。Source1:基于Port的,通过内核和其他线程通信,接收、分发系统事件。这种Source能主动唤醒RunLoop的线程。创建常驻线程就是在线程中添加一个NSport来实现的。
kCFRunLoopDefaultMode:默认模式,主线程是在这个运行模式下运行UITrackingRunLoopMode:跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响)UIInitializationRunLoopMode:在刚启动App时第进入的第一个 Mode,启动完成后就不再使用GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到kCFRunLoopCommonModes:伪模式,不是一种真正的运行模式,实际是kCFRunLoopDefaultMode 和 UITrackingRunLoopMode的结合。NSDictionary里。只能在当前线程中操作当前线程的runloop,不能操作其他线程的runloop 。详见内部实现1RunLoop,只有获取的时候才会创建[[NSRunLoop currentRunLoop] run]main线程默认开启Runloop的NSRunLoop隶属于:Foundation,而CFRunLoop隶属于Core FoundationCFRunLoop需要自己手动管理内存,实际上Core Foundation大部分都是手动管理
runloop实际上是一个do...while监听事件循环,在不同的model下接受不同的事件(time/source/observer),直到线程结束被销毁。