基于RunLoop的事件处理流程

按键(HOME键、锁屏键、音量键等)、传感器(摇晃、加速等)、触摸屏幕等【物理事件】会触发IOKit.framework生成一个IOHIDEvent对象,然后SpringBoard会接收这个对象并通过mach port发给当前App的进程;接下来进程会触发RunLoop的基于port的Source1回调一个__IOHIDEventSystemClientQueueCallback()的API,这个API会相应触发Source0来调用__UIApplicationHandleEventQueue(),而此API再将传递到此的IOHIDEvent处理包装成上层所熟悉的UIEvent。最后UIEvent会被分发给UIWindow根据Respond chain来响应事件。

梳理整个流程如下:

物理事件 (按键、传感器、触摸等)

|

IOHIDEvent (由IOKit.framework生成,SpringBoard接收)

|

App进程 (由mach port内核消息通信机制传递Event,SpringBoard->App)

|

触发Source1

|

回调 __IOHIDEventSystemClientQueueCallback()

|

触发Source0

|

回调__UIApplicationHandleEventQueue()

|

将IOHIDEvent封装成UIEvent

|

识别此事件是UIGesture或屏幕旋转等

|

分发UIWindow

|

根据响应链交给对应的responder进行事件回调

而这整个事件处理流程是基于RunLoop的基本处理循环进行的。在main函数开始后,主线程的runloop对象被创建完。如UIEvent、UI绘制等会统一在主线程的runloop对象的即将进入休眠前的时间点触发各自对应的代理回调方法,然后runloop进入休眠,直到被timer定时器或Source1发来的内核消息事件唤醒,再分别对Timer、Source0、Source1发来的事件进行处理回调。

你可能感兴趣的:(基于RunLoop的事件处理流程)