Runloop 的应用场景?
- NSTimer定时器,本质上是runloop source, runloop在一个循环开始后就会调用runloop source(在source 0之前)。由于runloop在一个循环周期内要处理很多事情,因此NSTimer有可能不准。
- 线程保活,在线程开始执行后,为common mode添加一个 mach port 作为输入源,这样runloop便会一直执行下去, 于是线程不会在方法执行完后就退出。
- 处理滑动过程中定时器停止的问题。由于滑动时,runloop mode会自动切换到UITracking mode,而这个mode是不包含定时器事件的,因此滑动过程中定时器会停止,要解决这个问题,就需要将当前mode切换到common modes,common modes其实是一个伪模式,他里面包含了default mode和uitracking mode,因此既能处理滑动事件又能响应定时器。或者是在定时器初始化的时候就将其加入到 uitracking mode。
- AutoRelease pool . Autorelease pool 向runloop注册了观察者,在进入循环、退出循环以及进入休眠、从休眠唤醒的时候会进入autorelease pool的入栈、出栈的操作,以完成对象的自动释放。
- 基于mach port的线程间通信。比如转发子线程的消息到主线程
Runloop的输入源有哪些?
- Source0 , 比如触摸事件、 performSelector: onThread的事件。
- Source1 , 比如基于port的线程间的通信,系统事件的捕捉(触摸事件会传递给source0)
- 定时器,比如 NSTimer, performSelector:withObject: afterDelay(底层通过NSTimer实现)。
- Observers,监听runloop的状态、UI的刷新(before waiting), autorelease pool(before waiting),在RunLoop休眠之前都会去执行UI的刷新啊、Autorelease pool的释放等
Source0和Source1区别:
Source0不能主动触发事件。Source0只有一个回调(函数指针),使用时先调用 CFRunLoopSourceSignal (source)将Source 标记为待处理,然后调用 CFRunLoopWakeUp (runloop) 唤醒 RunLoop,让RunLoop处理事件。
Source1 能主动唤醒 RunLoop 的线程。Source1有一个 mach_port 和一个回调(函数指针),被用于通过内核和其他线程相互发送消息。
网友评论