RunLoop 的概念
一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。如果我们需要一个机制,让线程能随时处理事件但并不退出。RunLoop可以简单的理解为一个循环函数,不断循环执行使线程不退出。
线程执行了这个函数后,就会一直处于这个函数内部 “等待->接受消息->处理” 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。
RunLoop 对外的接口
也可以说是RunLoop要处理的任务:
img
- source(要处理的任务,就是处理系统内核和其他线程发送来的消息:例如硬件事件触屏、锁屏、摇晃等,和线程间用过mach_port发的消息)
- 定时器
- 观察者。用于观察RunLoop自身的状态变化。
RunLoop 的 Mode
根据当前手机的操作状态,RunLoop的模式会切换。例如没有操作时,mode为kCFRunLoopDefaultMode,滑动tableView时,mode切换为 UITrackingRunLoopMode。(常见问题:滑动tableView时timer失效,因为未将timer加入当前RunLoop的common模式中)
苹果用 RunLoop 实现的功能
AutoreleasePool
RunLoop开始时创建AutoreleasePool。这期间的autoRelease的对象,都被加入这个AutoreleasePool中。本次RunLoop循环结束时释放该AutoreleasePool。
界面更新
本次RunLoop循环将要结束前,完成需要更新的UI的layout和绘制(当修改UI后,这些UI会被标记为需要更新)
触摸事件 手势识别
当一个硬件操作(触摸/锁屏/摇晃等)发生后,系统把它们包装成事件转发给需要的App进程的线程的RunLoop中,随后在应用内进行触摸事件分发和手势识别,并触发手势的回调函数。
定时器
一个 NSTimer 注册到 RunLoop 后,RunLoop 会为其重复的时间点注册好事件
PerformSelecter:onThread:
实际上其会创建一个 Timer 加到对应的线程的RunLoop 中
网络请求
后台线程进行持续不断的数据传输,然后通过RunLoop在线程间传递下载的数据。
想深入了解的同学,请移步这里 深入理解RunLoop
网友评论