美文网首页
RunLoop概念与响应者链

RunLoop概念与响应者链

作者: anthony1234567 | 来源:发表于2020-03-01 02:12 被阅读0次

    一.RunLoop简介

    什么是RunLoop?

    RunLoop就是运行循环,在程序运行的过程中循环做一些事情,如果没有RunLoop程序执行完毕就会立刻退出,如果有RunLoop程序会一直运行,并且时刻在等待用户的输入操作。RunLoop在有任务的时候会被唤醒,没有任务的时候会进入休眠状态,节省CPU资源,提高程序性能。

    二.RunLoop的开启

    当我们打开APP的时候,首先进入的是UIApplicationMain函数,RunLoop的作用是维持程序不退出,说明在UIApplicationMain函数中就启动了RunLoop,每一个进程对应一条主线程,主线程默认开启Runloop。

    三.响应者链

    当用户在界面发生一个点击手势事件,首先由IOKit.framwork产生一个IOHIDEvent对象,并通过mach port(轻量级的进程间通信的方式) 转发到SpringBoard.app(这个应用程序用来管理IOS的主屏幕),然后通过mach port将事情转发到前台APP进程,然后触发由APP在RunLoop注册的Source1(由Runloop和内核管理,mach port驱动)来处理事件,Source1内部调用 IOHIDEventSystemClientQueueCallBack(),IOHIDEventSystemClientQueueCallBack()内部回调了Source0(处理App内部事件,App自己负责管理(触发),如UIEvent,CFSocket)生成了UIEvent事情,并加入事情处理队列中,UIApplication从事件队列中取出事情进行派发,开始了hit-Testing的过程。

    四.如何找到第一响应者?

    UIApplication会首先把事件传给UIWindow,UIWindow会使用hitTest:withEvent:方法找到此次触摸事件初始点所在的视图,再到这个视图之后他会调用视图的touchesBegan:withEvent:方法来处理事件。

    举个例子:

    当用户点击ViewD所在的区域时会进行以下hit-Testing:

    1、ViewA 的 pointInside 返回 YES,因为触摸点在其 bounds 内。遍历 ViewA 的两个 subview;

    2、ViewB 的 pointInside 返回 NO,因为触摸点不在其 bounds 内,ViewB 的 hitTest 方法返回 nil。而且发生一票否决,在 ViewB 上的所有 subviews 受到牵连将不再进行 hit-Testing 处理。

    3、ViewC 的 pointInside 返回 YES,因为触摸点在其 bounds 范围内,ViewC 的 hitTest 方法返回默认处理,也就是return [super hitTest:point withEvent:event];遍历 ViewC 的两个 subview。

    4、ViewD的 pointInside 返回 YES,因为触摸点在其 bounds 范围内,且ViewD 没有 subview,因此 hitTest 方法返回其自己。hitTesting view 找到,结束处理。

    需要注意的地方:

    1、hitTest 方法调用 pointInside 方法;

    2、hit-Testing 过程是从 superView 向 subView 逐级传递,也就是从层次树的根节点向叶子节点传递;

    3、遇到以下设置时,view 的 pointInside 将返回NO,hitTest 方法返回 nil:

    view.isHidden=YES;

    view.alpha<=0.01;

    view.userInterfaceEnable=NO;

    control.enable=NO;(UIControl的属性)

    五.事件响应

    1、如果 hit-test view 或 first responder 不处理此事件,则将事件传递给其 nextResponder 处理,若有 UIViewController 对象则传递给 UIViewController,传递给其 superView。

    2、如果 view 的 viewController 也不处理事件,则 viewController 将事件传递给其管理 view 的 superView。

    3、视图层级结构的顶级为 UIWindow 对象,如果 window 仍不处理此事件,传递给 UIApplication.

    4、若 UIApplication 对象不处理此事件,则事件被丢弃。

    相关文章

      网友评论

          本文标题:RunLoop概念与响应者链

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