本期概要
- 话题:WWDC 22 Call to Code
- 面试模块:事件响应与传递
- 优秀博客:复习 iOS 的 rebase 和 bind
- 学习资料:闲话 Swift 协程
- 开发工具:AppleParty 是三七互娱旗下37手游 iOS 团队研发,实现快速操作 App Store Connect 后台的自动化 macOS 工具。
本期话题
WWDC 22 Call to Code
Apple 宣布了 WWDC 22 的相关事项,时间是 6 月 6 号到 10 号,形式还是线上播放。苹果一向喜欢玩彩蛋,我们可以尝试从这张图片里获取一些信息。图片主体是 Swift 图标,更准确的说应该是 SwiftUI 的图标,图标边缘透出的光亮有一种黎明到来,开启新篇章的感觉,所以很可能 SwiftUI 将迎来重大更新。就可联想的范围来说,什么样的更新才算重大呢,对标 Flutter,有没有可能支持全栈:Windows、Linux、Web 等平台?这个想法确实能配得上黎明到来,至于是否会实现,还是会有别的我们想不到的大更新,就让我们等待它的到来吧!
同时 Swift Student Challenge 将继续举办,学生们可以通过 Swift Playgrounds 创造有趣的项目。项目提交截止时间是 4 月 25 号,获奖者将获得 Apple 提供的一件 WWDC22 主题外套,一套定制的别针套装和一年的开发者会员资格。活动详情可以点击 Swift Student Challenge 查看。
面试解析
整理编辑:JY
事件响应与传递
当指尖触碰屏幕,触摸事件由触屏生成后如何传递到当前应用?
通过 IOKit.framework
事件发生,被封装为 IOHIDEvent
对象,然后通过 mach port
转发到 SpringBoard
(也就是桌面)。然后再通过mach port
转发给当前 APP 的主线程,主线程Runloop
的Source1
触发,Source1
回调内部触发Source0回调
,Source0
的回调内部将事件封装成UIEvent
,然后调用UIApplication
的sendEvent
将UIEvent
传给了UIWindow
。
souce1
回调方法:__IOHIDEventSystemClientQueueCallback()
souce0
回调方法:__UIApplicationHandleEventQueue()
寻找最佳响应者,这个过程也就是hit-testing
,确定了响应链,接下来就是传递事件。
如果事件找不到能够响应的对象,最终会释放掉。Runloop
在事件处理完后也会睡眠等待下一次事件。
寻找事件的最佳响应者(Hit-Testing)
当 APP 接受到触摸事件后,会被放入到当前应用的一个事件队列中(先发生先执行),出队后,Application
首先将事件传递给当前应用最后显示的UIWindow
,询问是否能够响应事件,若窗口能够响应事件,则向下传递子视图是否能响应事件,优先询问后添加的视图的子视图,如果视图没有能够响应的子视图了,则自身就是最合适的响应者。
objectivec - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { //3种状态无法响应事件 if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil; //触摸点若不在当前视图上则无法响应事件 if ([self pointInside:point withEvent:event] == NO) return nil; //从后往前遍历子视图数组 int count = (int)self.subviews.count; for (int i = count - 1; i >= 0; i--) { // 获取子视图 UIVie