RunLoop顾名思义就是程序在运行过程中循环做一些事情.如果没有RunLoop的话,程序运行结束以后就会马上退出的.而我们OC的main函数系统自动为我们创建了RunLoop函数,所以程序并不会马上退出,而是保持运行状态,监听用户的相关操作.
RunLoop的基本作用:
RunLoop 的应用范畴:
RunLoop 对象:
ios中有2套API来访问和使用RunLoop:
NSRunLoop和CFRunLoopRef都代表着RunLoop对象,而 NSRunLoop是对CFRunLoopRef的一层OC封装.
获取RunLoop的对象:
[NSRunLoop currentRunLoop];//获取当前线程的RunLoop
[NSRunLoop mainRunLoop];//获取主线程的RunLoop
RunLoop 相关的五个类:
NSRunLoop对象是OC对象,是对CFRunLoopRef的封装,可以通过getCFRunLoop方法获取其对应的CFRunLoopRef对象。注意,NSRunLoop不是线程安全的,但CFRunLoopRef是线程安全的
NSRunLoop对象是一系列RunLoopMode的集合,每个mode包括有这个模式下所有的Source源、Timer源和观察者。每次RunLoop调用的时候都只能调用其中的一个mode,接收这个mode下的源,通知这个mode下的观察者。这样设计的主要目的就是为了隔离各个模式下的源和观察者,使其不相互影响,model有一下常用的五种:
2.1.kCFRunLoopDefaultMode:
App默认的mode,通常主线程就是在这个mode下运行的
2.2.UITrackingRunLoopMode:
界面跟踪时的mode,一般用于ScrollView滚动的时候追踪的,保证滑动的时候不受其他model的影响
2.3.UIInitializationRunLoopMode:
在刚启动 App 时进入的第一个 Mode,启动完成后就不再使用
2.4.GSEventReceiveRunLoopMode:
接受系统事件的内部 Mode,一般用不到
2.5.kCFRunLoopCommonModes:
占位mode,可以向其中添加其他mode用以检测多个mode的事件
3.CFRunLoopSourceRef--->事件源产生的地方
4.CFRunLoopTimerRef-->是基于事件的触发器,其中包含一段时间长度、延期容忍度和一个函数指针(回调方法)。当其加入到RunLoop中时,RunLoop会注册一个时间点,当到达这个时间点后,会触发对应的事件。
5.CFRunLoopObserverRef-->RunLoop的观察者。每个观察者都可以观察RunLoop在某个模式下事件的触发并处理
kCFRunLoopEntry:即将进入runLoop
kCFRunLoopBeforeTimers:即将处理Timer
kCFRunLoopBeforeSources:即将处理Source
kCFRunLoopBeforeWaiting:即将进入休眠
kCFRunLoopAfterWaiting:刚从休眠中被唤醒
kCFRunLoopExit:即将退出RunLoop
CFRunLoopModeRef代表RunLoop的运行模式
mode的分别处理的事件:
首先CFRunloopRef这个对象里面有一个CFMutableSetRef _modes这个集合,而_modes这个集合里面装着一堆CFRunLoopModeRef model,当然有其中一个model代表当前的model(_currentModel).而CFRunLoopModeRef里面又装着很多CFMutableSetRef _sources0集合,CFMutableSetRef _sources1集合(sources0和sources1这个集合里面装着一堆CFRunLoopSourceRef对象),CFMutableArrayRef _observers集合(这个 集合里面装着一堆CFRunLoopObserverRef对象),tCFMutableArrayRef _timers集合(这个集合里面装着一堆CFRunLoopTimerRef对象)
源码解析
/**
第一种方法:
1.此方法的创建定时器默认会加到了NSRunLoop中,并设置运行模式为默认.
2.如是想在子线程中开启NSRunLoop,需要手动开启:
NSRunLoop*runllop=[NSRunLoop currentRunLoop];等到线程销毁的时候currentRunLoop的对象也随之销毁;
3.在子线程的定时器,需要手动加入runLoop,不要忘记调用run方法
*/
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(startTime) userInfo:nil repeats:YES];
/**
第二种方法:
1.此方法创建需要手动将定时器添加到 NSRunLoop中,指定的运行模式是default,但是有滚动事件的时候,定时器就会停止工作.
解决方案:更改NSRunLoop的运行模式.UITrackingRunLoopMode界面追踪,此模式只有发生滚动事件的时候才会开启定时器.若是任何时候都会开启定时器:NSRunLoopCommonModes(NSRunLoopCommonModes=NSDefaultRunLoopMode+UITrackingRunLoopMode).凡是添加到NSRunLoopCommonModes中的事件都会被同时添加到CommonMode的运行模式上的.
*/
NSTimer*timer=[NSTimer timerWithTimeInterval:3.0 target:self selector:@selector(startTime) userInfo:nil repeats:YES];
//下面这三种情况根据实际情况加入RunLoop
[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop]addTimer:timer forMode:UITrackingRunLoopMode];
将Timer添加到CommonModes类型里面.
视频讲解:
视频一:runLoop使用详情,视频讲解(一)-IOS文档类资源-CSDN下载
视频二:runLoop使用详情,视频讲解(二)-IOS文档类资源-CSDN下载
视频三:runLoop使用详情,视频讲解(三)-IOS文档类资源-CSDN下载
视频四:runLoop使用详情,视频讲解(四)-IOS文档类资源-CSDN下载
视频五:runLoop使用详情,视频讲解(五)-IOS文档类资源-CSDN下载
视频六:runLoop使用详情,视频讲解(六)-IOS文档类资源-CSDN下载
视频七:runLoop使用详情,视频讲解(七)-IOS文档类资源-CSDN下载
视频八:runLoop使用详情,视频讲解(八)-IOS文档类资源-CSDN下载
视频九:runLoop使用详情,视频讲解(九)-IOS文档类资源-CSDN下载