RunLoop 的 CommonModes ,其实不是一个真正的 modes,而是一个伪 mode.. ,每个 _CFRunLoopRef 的数据结构大致是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock; /* locked for accessing mode list */ __CFPort _wakeUpPort; // used for CFRunLoopWakeUp Boolean _unused; volatile _per_run_data *_perRunData; // reset for runs of the run loop pthread_t _pthread; //runloop对应的线程 uint32_t _winthread; CFMutableSetRef _commonModes;//存储的是字符串,记录所有标记为common的mode CFMutableSetRef _commonModeItems;//存储所有commonMode的item(source、timer、observer) CFRunLoopModeRef _currentMode;//当前运行的mode CFMutableSetRef _modes;//存储的是CFRunLoopModeRef, struct _block_item *_blocks_head; struct _block_item *_blocks_tail; CFAbsoluteTime _runTime; CFAbsoluteTime _sleepTime; CFTypeRef _counterpart; };
|
可以看到,里面有个 _commonModes 的集合,里面存储着被标记为 common 的 Modes 的字符串,主线程的 RunLoop 中,DefaultMode 和 TrackingMode 是被标记为 _commonMode 的。结构体中而且还一个 _commonModeItems 的集合,这个集合里,存储着所有 commonMode 的 item,比如 source、timer、observer。
每当 RunLoop 中的内容发生变化时,都会将 _commonModeItems 中的内容,自动同步到被标记为 _commonMode 的 mode 中,比如:
当我们将一个 timer 加入 commonMode,那么他们会被存储到 _commonModeItems 中,然后 RunLoop 会遍历 _commonModes 中的 mode ,然后将 timer 加入到这些 mode 中。