面试题答案
一键面试iOS手势识别系统工作原理(基于Objective-C框架底层原理)
- 事件传递:当用户触摸屏幕时,系统会生成一个触摸事件(
UITouch
),并将其放入事件队列。UIApplication
从事件队列中取出事件,开始寻找合适的视图来处理该事件。它会从窗口的根视图开始,通过hitTest:withEvent:
方法遍历视图层级,找到最适合处理该事件的视图(即命中测试视图)。 - 手势识别器的注册与管理:开发者可以在视图上添加各种手势识别器(
UIGestureRecognizer
的子类,如UITapGestureRecognizer
、UIPanGestureRecognizer
等)。这些手势识别器会被添加到视图的gestureRecognizers
数组中。 - 手势识别过程:手势识别器有自己的状态机,常见状态包括
UIGestureRecognizerStatePossible
(可能状态,初始状态)、UIGestureRecognizerStateBegan
(开始状态)、UIGestureRecognizerStateChanged
(变化状态)、UIGestureRecognizerStateEnded
(结束状态)等。当触摸事件传递到包含手势识别器的视图时,手势识别器会根据触摸点的位置、数量、移动距离等信息,在其状态机中进行状态转换。例如,对于点击手势,当检测到触摸点的数量和点击次数符合设定时,手势识别器会转换到UIGestureRecognizerStateEnded
状态,并触发相应的回调方法。
实现自定义复杂手势识别时优化代码结构与性能的方面
- 代码结构优化
- 模块化设计:将复杂手势识别的逻辑拆分成多个独立的模块,每个模块负责处理手势识别的一个特定部分,例如手势起始点检测、轨迹跟踪、结束条件判断等。这样可以提高代码的可读性和可维护性。
- 继承与多态:通过继承
UIGestureRecognizer
类,创建自定义手势识别器类。在子类中重写父类的方法,如touchesBegan:withEvent:
、touchesMoved:withEvent:
、touchesEnded:withEvent:
等,根据自定义手势的规则进行处理。利用多态性,可以方便地在不同场景中使用自定义手势识别器。 - 数据结构选择:选择合适的数据结构来存储手势识别过程中的数据,如使用数组存储触摸点的轨迹,或者使用字典存储特定手势的相关参数。合理的数据结构选择可以提高数据的访问和处理效率。
- 性能优化
- 减少计算量:在手势识别过程中,尽量减少不必要的计算。例如,对于复杂手势轨迹的判断,可以采用抽样的方式,只在关键节点进行复杂计算,而不是对每个触摸点都进行完整计算。
- 优化事件处理:合理设置手势识别器的
cancelsTouchesInView
和delaysTouchesBegan
等属性,避免不必要的事件传递和处理,提高响应速度。同时,注意手势识别器之间的冲突处理,避免因为多个手势识别器同时响应而导致性能问题。 - 缓存与复用:对于一些重复计算的结果,可以进行缓存。例如,计算手势轨迹的长度时,如果多次需要该值,可以缓存起来,避免重复计算。此外,对于一些临时对象,如用于存储中间计算结果的对象,可以考虑复用,减少内存分配和释放的开销。