1.runloop的概念
runloop 是一个循环方式,系统给我们提供的一种事件循环机制,保证程序可以持续的接受并处理事件,在事件完成后,时
使程序处在睡眠状态等待唤醒
2.runloop的循环结构 (线程与runloop之间是一一对应的关系)
等待事件的传入 ————线程处于睡眠状态
事件传入 ------唤醒线程
执行事件 ---- 完成线程以后进入睡眠状态
3.runloop的作用
使程序一直运行,并且接收用户的输入 (程序处在睡眠状态)
决定应用程序在何时应该处理那些事件(runloop 只能传入一个mode 当传入新的mode时,强制的结束上一个循环,开始新的循环)
调用解耦合 (MassageQueue 接收消息的任务循环执行,类似于异步)
4.runloop的结构
4.1说明; 线程和runloop 是一一对应的,一个线程对应着一个runloop ,主线程的runloop时默认执行的,子线程的runloop是默认执行的,zixian
子线程的runloop需要手动的启动,启动方式如下:
-(void)run;
-(void)runUntilDate:(NSDate *)limitDate;
-(BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate;
4.2CFRunLoopRef :系统对CFRunLoopRef进行封装,我们可以直接操作的runloop类是NSRunloop ,当然我们不能直接使用currentRunLooop
‘mainRunLoop获取
4.3CFRunloopMode :事件执行的模式;
系统开放可以去设置的事件模式 ,一个runloop里面只能存在一个事件模式
NSDefaultRunLoopMode : 系统默认的
NSRunloopCommonModes :common完成了一次占位,当这个模式的事件传递进来时,强制结束
上一次的循环,开始新的传入事件的循环
CFRunloopSourcesrunloop :事件的传递,接受传递过来的事件,交给线程执行
CFRunloopTimer runloop的时间源
CFRunloopObserver runloop 的监听者 可以监听runloop所处的状态
5. AutoreleasePool中的对象是什么时候被释放的?
当runloop结束一次循环的时候,就会释当前处于活跃状态的队形进行释放,当程序结束时(遇到” }“时),再把自动释放池中的数据全部释放
6.runloop的实现原理
7.定时器
NSTimer 其实就是CFRunloopTimerRef。一个NSTimer注册到Runloop后,Runloop会为其重复的时间点注册好事件,
runloop为了节省资源,并不会在非常准确的时间点回调这个Timer ,timer有个属性叫做Tolerance(宽容度),标示了当
时间点到后,允许有多少最大误差,如果某个时间点被错过了,例如执行一个很长任务,则那个时间点的回调就会跳过去,不会
不会延后执行 (例如之前用NSTimer 做的倒计时 运行到最后总是有一块地方没有减少)
CADisplayLink 是一个和屏幕刷新率一致的定时器 (但实际实现原理更复杂,和NSTimer并不一样 ,其内部实际操作了一个Source),如果在两次屏幕刷新
之间执行了一个长任务,那其中就会有一帧被跳过去(和NSTimer是一样的),造成界面卡顿的感觉
8.performSelector
当调用NSObject的performSelector :afterDelay:后,实际上内部会创建一个Timer并添加到当前线程的runloop中,所以当前线程没有runloop则这个方法会失效
当调用performSelector :onThread:时;实际上其会创建一个timer添加到对应的线程里,同样的,如果对应线程没有runloop 该方法也会失效;