面试题答案
一键面试- 事件产生与传递起点:
- 当触摸事件发生时,系统首先会将事件添加到由UIApplication管理的事件队列中。
- UIApplication从事件队列中取出最前面的事件,并将事件传递给应用程序的主窗口(UIWindow)。这是事件传递的起点,因为主窗口是应用程序视图层级结构的根容器。
- 主窗口寻找初始响应者:
- 主窗口调用
hitTest:withEvent:
方法开始寻找合适的视图来处理该事件。hitTest:withEvent:
方法的作用是从视图层级的最顶层开始遍历,找到那个最合适的视图来响应触摸事件。 - 主窗口自身调用
pointInside:withEvent:
方法,判断触摸点是否在主窗口的边界范围内。如果触摸点在主窗口范围内,主窗口会遍历它的所有子视图(从后添加的子视图开始遍历,因为后添加的子视图在层级上处于上方),对每个子视图调用hitTest:withEvent:
方法。
- 主窗口调用
- 子视图的事件传递处理:
- 子视图接收到
hitTest:withEvent:
消息后,同样先调用自身的pointInside:withEvent:
方法,判断触摸点是否在自己的边界范围内。 - 如果触摸点在子视图范围内,该子视图会继续遍历它自己的子视图(同样从后添加的子视图开始),重复上述调用
hitTest:withEvent:
方法的过程,如此递归下去。 - 如果触摸点不在子视图范围内,该子视图会返回
nil
,表示自己不是合适的响应者,然后它的父视图会继续检查下一个子视图。
- 子视图接收到
- 找到初始响应者:
- 当某个子视图的
pointInside:withEvent:
方法返回YES
,并且它没有子视图或者它的所有子视图的hitTest:withEvent:
方法都返回nil
时,这个子视图就被认为是初始响应者,也就是最合适处理该触摸事件的视图。 - 一旦找到初始响应者,事件就会沿着视图层级从父视图传递到这个初始响应者。
- 当某个子视图的
- 响应者链与事件响应:
- 初始响应者会尝试处理该事件。如果初始响应者不处理事件(例如,它没有实现相应的触摸事件处理方法),事件会沿着响应者链向上传递。
- 响应者链是由响应者对象(如视图、视图控制器等)组成的链条。在视图层级中,初始响应者的下一个响应者通常是它的父视图,父视图的下一个响应者是它的父视图,以此类推,直到视图控制器、窗口,最后到应用程序本身。
- 沿着响应者链,每个响应者都有机会处理事件,直到事件被处理或者到达应用程序本身且未被处理。如果事件最终未被处理,应用程序可能会默认忽略该事件。