UITableView
Cell的复用机制
UITableView内部维护了一个cell的重用缓存池队列,当屏幕上的Cell移动出屏幕后,系统就会将这个Cell放入重用池中,当下一个Cell要呈现时,系统就会去重用池中查找是否有可重用对象,如果有就拿出复用,如果没有就创建。系统会通过绑定标识符来查找对应类型的Cell。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: momentCellId, for: indexPath) as! MomentCell
return cell
}
UITableView在多线程下数据同步
并发访问和数据拷贝
串行访问
缺点:如果两个操作都很耗时的话就会很慢。
事件传递链和视图响应链条
事件传递链
事件通常我们指的是用户的触摸事件。
事件的传递流程如下图所示:
- 我们点击屏幕产生触摸事件,系统将这个事件加入到一个由
UIApplication
管理的事件队列中,UIApplication
会从消息队列里取事件分发下去,首先传给UIWindow
- 在
UIWindow
中就会调用hitTest:withEvent:
方法去返回一个最终响应的视图 - 在
hitTest:withEvent:
方法中就会去调用pointInside: withEvent:
去判断当前点击的point
是否在UIWindow
范围内,如果是的话,就会去遍历它的子视图来查找最终响应的子视图 - 遍历的方式是使用倒序的方式来遍历子视图,也就是说最后添加的子视图会最先遍历,在每一个视图中都回去调用它的
hitTest:withEvent:
方法,可以理解为是一个递归调用 - 最终会返回一个响应视图,如果返回视图有值,那么这个视图就作为最终响应视图,结束整个事件传递;如果没有值,那么就会将
UIWindow
作为响应者
视图响应链
在我们找到这个响应视图之后,事件就会由这个视图来处理,也就是hitTest:withEvent:
方法返回的视图,如果它无法响应事件,那么我们就要传递给下一个响应者。这里就会涉及到我们的响应链。
响应链的流程就如下所示:
流程描述:
- 如果
view
的控制器存在,就传递给控制器处理;如果控制器不存在,则传递给它的父视图 - 在视图层次结构的最顶层,如果也不能处理收到的事件,则将事件传递给
UIWindow
对象进行处理 - 如果
UIWindow
对象也不处理,则将事件传递给UIApplication
对象 - 如果
UIApplication
也不能处理该事件,则将该事件丢弃