美文网首页
iOS事件处理机制

iOS事件处理机制

作者: hehc08 | 来源:发表于2019-02-17 18:36 被阅读0次

    事件类型

    iOS的事件可以分为三类:触摸事件,加速计事件,远程控制事件

    iOS中不是任何对象都能处理对象,只有继承了UIResponder的对象才能接收并处理事件. ---->响应者对象

    typedef NS_ENUM(NSInteger, UIEventType) {
        UIEventTypeTouches,
        UIEventTypeMotion,
        UIEventTypeRemoteControl,
    };
    
    //事件类型
    @property(nonatomic,readonly) UIEventType     type 
    @property(nonatomic,readonly) UIEventSubtype  subtype 
    //事件产生的时间
    @property(nonatomic,readonly) NSTimeInterval  timestamp;
    

    事件的传递

    • 系统把事件加入到一个由UIApplication管理的事件队列中
      之所以加入队列而不是栈是因为队列先进先出,意味着先产生的事件,先处理

    • 然后,事件会按照UIApplication -> UIWindow -> SuperView -> SubView的顺序不断的检测

    • 而检测就是靠两个方法hitTest与pointInside

    事件与runloop

    当我们触发了事件(触摸/锁屏/摇晃等)后,

    • IOKit.framework生成一个 IOHIDEvent事件

    • IOKit是苹果的硬件驱动框架

    • 由它进行底层接口的抽象封装与系统进行交互传递硬件感应的事件

    • 它专门处理用户交互设备,由IOHIDServicesIOHIDDisplays两部分组成

    • 其中IOHIDServices是专门处理用户交互的,它会将事件封装成IOHIDEvents对象,详细请看这里

    • 然后这些事件又由SpringBoard接收,它只接收收按键(锁屏/静音等),触摸,加速,接近传感器等几种 Event

    • 接着用mach port转发给需要的App进程

    • Source1 接收IOHIDEvent,之后再回调__IOHIDEventSystemClientQueueCallback()内触发的Source0

    • Source0再触发的 __dispatchPreprocessEventFromEventQueue()

    • __dispatchPreprocessEventFromEventQueue()IOHIDEvent处理包装成UIEvent进行处理分发,我们平时的UIGesture/处理屏幕旋转/发送给 UIWindow/UIButton 点击、touchesBegin/Move/End/Cancel这些事件,都是在这个回调中完成。

    image.png
    0 - [AView touchesBegan:withEvent
    1 - [UIWindow _sendTouchesForEvent]
    2 - [UIWindow sendEvent]           
    3 - [UIApplication sendEvent]      
    4 __dispatchPreprocessEventFromEventQueue
    5 __handleEventQueueInternal
    6 _CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION_
    7 _CFRunLOOPDoSource0
    8 _CFRunLOOPDoSources1
    9 _CFRunLoopRun
    10 _CFRunLoopRunSpecific
    11 GSEventRunModal
    12 UIApplication
    13 main
    14 start
    

    手势识别

    • 当上面的 __dispatchPreprocessEventFromEventQueue() 识别了一个手势时,其首先会调用 Cancel 将当前的 touchesBegin/Move/End 系列回调打断。随后系统将对应的 UIGestureRecognizer 标记为待处理。

    • 苹果注册了一个 Observer 监测 BeforeWaiting (Loop即将进入休眠) 事件,这个Observer的回调函数是 _UIGestureRecognizerUpdateObserver(),其内部会获取所有刚被标记为待处理的 GestureRecognizer,并执行GestureRecognizer的回调。

    • 当有 UIGestureRecognizer 的变化(创建/销毁/状态改变)时,这个回调都会进行相应处理。

    相关文章

      网友评论

          本文标题:iOS事件处理机制

          本文链接:https://www.haomeiwen.com/subject/nffneqtx.html