《iOS之一起进大厂》系列iOS事件传递和视图响应流程

学而时习之,不亦说乎

感慨

好久没写博客了, 最近几年博客也荒废了很多。手也生了。
学而时习之,不经常复习总结,学了也会很快忘记。
好像学了很多知识,用了很多技术。 但是没有复习和文字总结, 回头看,好像什么都没记住。好记性不如烂笔头就是这个道理。
PS:
下面用模仿面试的问答模式,把相关的问题和知识点串联起来。 这样可以提高阅读体验,还可以加深记忆。

在这里插入图片描述

开始面试

一个穿着格子衬衫,大腹便便的中年男子拿着简历向你走来, 看着他头上快要绝顶的头发,心想这肯定是个iOS开发技术牛逼闪闪的老前辈。
还好看过杯子写《iOS之一起进大厂》系列,想想现在是满腹经纶,刚提到嗓子眼的心,又按下去了,淡定从容,一点都不虚好伐。

在这里插入图片描述

小伙子你好,看你简历提到熟悉iOS的事件响应机制,那你可以先说下事件的传递流程吗?

答:帅气逼人的面试官您好, 提到事件传递,就要提到这两个方法:

 1. (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
 2. (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event

hitTest返回响应事件的视图,哪个视图响应了事件,就返回该视图。
pointInside 判断某个点击位置是否在当前视图范围内。

事件传递的大概流程: 点击屏幕-UIApplication - UIWindow- hitTest - pointInsde。

  1. 用户点击屏幕时,产生一个触摸事件,事件加入到一个由UIApplication管理的事件队列中
  2. UIApplication从事件队列中取出最前面的事件进行分发处理,先发送事件给应用程序的主窗口(UIWindow)
  3. 主窗口会调用hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的UIView来处理触摸事件

那视图上有很多子视图,那怎么判断是哪个子视图对事件作出响应呢?

答: 用View的SubViews这个成员变量来遍历子视图实现。遍历的方式是用倒序方式来 遍历。 最后添加到UIWindow中的视图会最先遍历到。
可以理解为递归调用。每个视图都会调用自己的子视图的·hitTest方法来查找是否是自己响应了事件。

(hitTest:withEvent:其实是UIView的一个方法,UIWindow继承自UIView,因此主窗口UIWindow也是属于视图的一种)

整体的事件处理流程如图:
事件传递流程

问:既然理解了事件传递流程,那什么是事件响应链又是什么?

答:UIResponder是所有响应者对象的基类,只有继承了UIResponder的类才能响应touch事件。

优先是最上层的View响应事件,如果该View有父视图,下一个响应值就是父视图,如果没有就传给他对应的ViewController,这样从最上层View一直传到单例UIWindow对象,最后是单例UIApplication对象以终止,UIApplication的下一个响应者是nil,这样就是整个响应链的过程。

再说下事件分发:
iOS系统在处理事件时,通过UIApplication对象和每个UIWindow对象的sendEvent:方法将事件以消息的形式分发给具体处理此事件的第一响应者(First responder),使其有机会首先处理事件。如果第一响应者没有进行处理,第一响应者将事件将处理事件的责任传递给下一个,即当前responder对象的nextResponder。
实例代码打印响应链:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIResponder * next = [self nextResponder];
    NSMutableString * prefix = @"".mutableCopy;
    
    while (next != nil) {
        NSLog(@"%@%@", prefix, [next class]);
        [prefix appendString: @"--"];
        next = [next nextResponder];
    }
}

打印结果:

问:既然UIResponder这个类在响应链里这么重要,那再问一个跟UIResponder相关的简单问题,UIButton的父类或UIButton 继承关系是什么?

答:UIButton UIDatePicker这些控件 都继承了 UIControl, UIControl 继承于 UIView ,UIView继承于UIResponder。
UIView视图的继承关系

已经看到这里的同学,你们个个都是人才,我好喜欢。

在这里插入图片描述

创作不易,决绝白嫖,大家好我是空杯子,文章每周持续更新,如果这个文章写得还不错,觉得「杯子」我有写的东西对你有点用的话 求点赞👍
求关注❤求分享

求 点关注,加收藏,求分享

如果本篇博客有任何错误,请批评指教,不胜感激 !

在微信公众号中搜索 「 空杯子One 」 第一时间阅读和催更(比博客早一到两篇哟),还可以获取整理好的最全和新的iOS面试题和答案和iOS学习资料。 本文在GitHub https://github.com/schelling/iOSFamily 已经收录,那有一线大厂面试点思维导图,也整理了很多我的博客文档,欢迎Star和完善,大家面试可以参照考点复习,一起学而时习之,不亦说乎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值