按鍵(HOME鍵、鎖屏鍵、音量鍵等)、傳感器(搖晃、加速等)、觸摸屏幕等【物理事件】會(huì)觸發(fā)IOKit.framework生成一個(gè)IOHIDEvent對(duì)象,然后SpringBoard會(huì)接收這個(gè)對(duì)象并通過(guò)mach port發(fā)給當(dāng)前App的進(jìn)程;接下來(lái)進(jìn)程會(huì)觸發(fā)RunLoop的基于port的Source1回調(diào)一個(gè)__IOHIDEventSystemClientQueueCallback()的API,這個(gè)API會(huì)相應(yīng)觸發(fā)Source0來(lái)調(diào)用__UIApplicationHandleEventQueue(),而此API再將傳遞到此的IOHIDEvent處理包裝成上層所熟悉的UIEvent。最后UIEvent會(huì)被分發(fā)給UIWindow根據(jù)Respond chain來(lái)響應(yīng)事件。
梳理整個(gè)流程如下:
物理事件 (按鍵、傳感器、觸摸等)
|
IOHIDEvent (由IOKit.framework生成,SpringBoard接收)
|
App進(jìn)程 (由mach port內(nèi)核消息通信機(jī)制傳遞Event,SpringBoard->App)
|
觸發(fā)Source1
|
回調(diào) __IOHIDEventSystemClientQueueCallback()
|
觸發(fā)Source0
|
回調(diào)__UIApplicationHandleEventQueue()
|
將IOHIDEvent封裝成UIEvent
|
識(shí)別此事件是UIGesture或屏幕旋轉(zhuǎn)等
|
分發(fā)UIWindow
|
根據(jù)響應(yīng)鏈交給對(duì)應(yīng)的responder進(jìn)行事件回調(diào)
而這整個(gè)事件處理流程是基于RunLoop的基本處理循環(huán)進(jìn)行的。在main函數(shù)開(kāi)始后,主線程的runloop對(duì)象被創(chuàng)建完。如UIEvent、UI繪制等會(huì)統(tǒng)一在主線程的runloop對(duì)象的即將進(jìn)入休眠前的時(shí)間點(diǎn)觸發(fā)各自對(duì)應(yīng)的代理回調(diào)方法,然后runloop進(jìn)入休眠,直到被timer定時(shí)器或Source1發(fā)來(lái)的內(nèi)核消息事件喚醒,再分別對(duì)Timer、Source0、Source1發(fā)來(lái)的事件進(jìn)行處理回調(diào)。