一、概述
Runloop,运行循环,在程序启动后,一直循环的做一些事情。Runloop程序会一直运行并时刻等待用户的输入操作。Runloop在有任务的时候运行,没有任务的时候停止,节省资源,提高性能。
二、Runloop作用
1.保持程序的持续运行,一个程序对应一条主线程,主线程对应Runloop,Runloop保证主线程不销毁;
2.处理程序中的各种事件:触摸、定时器、Selector;
3.节省资源,提高性能;
三、Runloop对象
NSRunLoop对象:Fundation框架(基于CFRunLoopRef)
[NSRunLoop currentRunLoop];// 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop];// 获得主线程的RunLoop对象
CFRunLoopRef对象:CoreFoundation
CFRunLoopGetCurrent();// 获得当前线程的RunLoop对象
CFRunLoopGetMain();// 获得主线程的RunLoop对象
四、Runloop与线程
每条线程都有唯一一个与之对应的RunLoop对象;
主线程的Runloop已经自动创建,子线程Runloop需要主动创建;
Runloop在第一次获取时创建,在线程结束时销毁;
五、Runloop Mode
Runloop Mode是 Source、Timer和Observer的集合,不同的Mode相互之间隔绝开来。Runloop在一个时刻只能跑在一个Mode下,处理这个Mode当中的Source、Timer和Observer。
Mode:指定事件在运行循环中的优先级
NSDefaultRunLoopMode:默认的mode,正常情况下都是在这个mode
NSConnectionReplyMode
NSModalPanelRunLoopMode
NSEventTrackingRunLoopMode:使用这个Mode去跟踪来自用户交互的事件(比如UITableView上下滑动)
NSRunLoopCommonModes:实际上是一个 Mode 的集合,默认包括 NSDefaultRunLoopMode 和 NSEventTrackingRunLoopMode
Source:
唤醒Runloop的事情,点击屏幕
source0:非系统事件
source1:系统事件
Timer:NSTimer
Observer:使用KVO监听runloop的状态变化,然后做出反应
Runloop运行图
经典问题:scrollView滑动,NSTimer停止。当停止滑动,NSTimer运行。
解决:(1)Mode切换,timer 的mode改为 NSRunLoopCommonModes
(2)使用GCD创建定时器
六、Runloop应用
1.常驻线程
当子线程执行完任务之后就会被销毁,如果我们需要开启子线程,并且让它在程序运行过程中永远存在,这时就用到了常驻线程:给子线程开启Runloop。
注意:创建子线程Runloop,在子线程中创建即可,并且runloop必须有一个Timer或Source保证runloop不空转。没有加入Timer或Source,或添加监听者,程序崩溃。
2.自动释放池
runloop内部有一个自动释放池,当runloop开启,创建一个自动释放池,在runloop休息之前会释放掉自动释放池的东西,然后重新创建一个新的空的自动释放池,当runloop被唤醒时,Timer、Source新的事件就会放到新的释放池中,runloop退出的时候会被释放。
3.Mode间的切换
主要用到scrollView与timer,imageView显示。
(1)当NSTimer每隔一段事件执行一些事情时滑动UIScrollView,NSTimer就会暂停,当停止滑动,NSTimer又会重新恢复情况。
解:让timer在两个模式下都可以运行,NSRunLoopCommonModes任何模式下都可以运行
[[NSRunLoop mainRunLoop] addTimer: timer forMode: NSRunLoopCommonModes];
(2)performSelector默认在NSDefaultRunLoopMode下运行,滑动scrollView时,图片不加载
解:[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"abc"]afterDelay:2.0 inModes:@[NSDefaultRunLoopMode,UITrackingRunLoopMode]];
网友评论