原文链接:https://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=400417748&idx=1&sn=0c5f6747dd192c5a0eea32bb4650c160&3rd=MzA3MDU4NTYzMw==&scene=6#rd
1、iOS RunLoop都干了什么
RunLoop是一个接收处理异步消息事件的循环,一个循环中:等待事件发生,然后将这个事件送到能处理它的地方。
RunLoop主要处理以下6类事件:
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__();
static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__();
①Observer事件,runloop中状态变化时进行通知。(微信卡顿监控就是利用这个事件通知来记录下最近一次main runloop活动时间,在另一个check线程中用定时器检测当前时间距离最后一次活动时间过久来判断在主线程中的处理逻辑耗时和卡主线程)。这里还需要特别注意,CAAnimation是由RunloopObserver触发回调来重绘,接下来会讲到。
②Block事件,非延迟的NSObject PerformSelector立即调用,dispatch_after立即调用,block回调。
③Main_Dispatch_Queue事件:GCD中dispatch到main queue的block会被dispatch到main loop执行。
④Timer事件:延迟的NSObject PerformSelector,延迟的dispatch_after,timer事件。
⑤Source0事件:处理如UIEvent,CFSocket这类事件。需要手动触发。触摸事件其实是Source1接收系统事件后在回调 __IOHIDEventSystemClientQueueCallback() 内触发的 Source0,Source0 再触发的 _UIApplicationHandleEventQueue()。source0一定是要唤醒runloop及时响应并执行的,如果runloop此时在休眠等待系统的 mach_msg事件,那么就会通过source1来唤醒runloop执行。
⑥Source1事件:处理系统内核的mach_msg事件。(推测CADisplayLink也是这里触发)。