RunLoop(消息循环):说白了就是一种事件监听循环。就好比是一个while循环,监听到事件就起来,没有就休息。
介绍:
它可以在不同模式下进行切换,iOS有五种模式,其中UIInitializationRunLoopModel应用程序启动时会使用,启动完成后将不再使用;GSEventReceiveRunLoopMode这个是接受系统内部的Model,通常做不到。还有UITrackingRunLoopMode、NSDefaultRunLoopMode、NSRunLoopCommonModes三种模式是我们通常用到的,下文中会详细讲解,其中NSRunLoopCommonModes是一个占位符,NSDefaultRunLoopMode和UITrackingRunLoopMode都会绑定这个占位符。
→ UITrackingRunLoopMode : (优先切换!!)这个模式就是当UI事件交互的时候Runloop切换到的模式!!!
场景:这一模式优先级最高,当UI事件交互的时候,都会优先切换到这一模式。
→ NSDefaultRunLoopMode :Runloop的默认模式!只要有事件就处理!
场景:默认模式,只要有事件就会自动切换到此模式。
→ NSRunLoopCommonModes :占位符!!(在默认下和UITrackingRunLoopMode下!)
场景:这个主要用在添加一个NSTimer到RunLoop中。是一个tag,本质上不是一个Mode,默认NSDefaultRunLoopMode和 NSTrackingRunLoopMode都绑定这个tag。基本作用:
1.保持程序的持续运行(这也是iOS程序为什么能一直不会死的原因)。
2.处理App中的各种事件(比如触摸事件、selector事件、定时器事件等)。
3.节省CPU资源,提高程序性能,有事件就起来,没有就休息。
说明:
1.如果没有Runloop,那么程序一启动就会退出,什么事情都做不了。
2.如果有了Runloop,那么相当于在内部有一个死循环,能够保证程序的持续运行。
3.main函数中的Runloop。
4.在UIApplication函数内部就启动了一个Runloop,函数返回一个int类型的值。
5.这个默认启动的Runloop是跟主线程相关联的。
RunLoop对象:
1.在iOS开发中有两套API来访问Runloop:(1).Foundation框架[NSRunloop]。(2).Core Foundation框架[CFRunloopRef]。
2.NSRunLoop和CFRunLoopRef都代表着RunLoop对象,它们是等价的,可以互相转换。
3.NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)。
Runloop与线程:
1.Runloop和线程的关系:一个Runloop对应着一条唯一的线程。
2.Runloop的创建:主线程Runloop已经创建好了,子线程的runloop需要手动创建。
3.Runloop的生命周期:在第一次获取时创建,在线程结束时销毁。
获得Runloop对象:
1.获得当前Runloop对象:
a. NSRunloop
NSRunLoop * runloop1 = [NSRunLoop currentRunLoop];
b.CFRunLoopRef
CFRunLoopRef runloop2 = CFRunLoopGetCurrent();
2.拿到当前应用程序的主Runloop(主线程对应的Runloop)
a.NSRunloop
NSRunLoop * runloop1 = [NSRunLoop mainRunLoop];
b.CFRunLoopRef
CFRunLoopRef runloop2 = CFRunLoopGetMain();
3.注意点:开一个子线程创建runloop,不是通过alloc init方法创建,而是直接通过调用currentRunLoop方法来创建,它本身是一个懒加载的。
4.在子线程中,如果不主动获取Runloop的话,那么子线程内部是不会创建Runloop的。可以下载CFRunloopRef的源码,搜索_CFRunloopGet0,查看代码。
5.Runloop对象是利用字典来进行存储,而且key是对应的线程Value为该线程对应的Runloop。
Runloop 总结
可以看出,RunLoop被开启的线程会一直存在。因为在没有事件发生的时候处于休眠状态,有事件发生的时候处于工作状态。以此来节约CPU资源。这样就可以让一个线程成为常驻线程,也就是说该线程一直存在。
RunLoop是iOS事件响应与任务处理最核心的机制,它贯穿iOS整个系统。
RunLoop是一种事件运行循环机制,是保持应用程序持续运行的一种机制。正是由于该机制的存在,应用程序才能在没有事件发生的时候处于休眠状态,有事件发生的时候处于工作状态。以此来节约CPU资源。这也是它的一大特点。
NSRunLoop是Cocoa框架中的类,与之对应的,在Core Foundation中是CFRunLoopRef类。两者的区别是前者不是线程安全的,后者是线程安全的,且两者可以相互转化。
RunLoop和线程的关系:
RunLoop是用来管理线程的,每个线程对应一个RunLoop对象。我们不可以去创建当前线程的RunLoop对象,但是我们可以去获取当前线程的RunLoop。RunLoop就是来监听该线程有无事件发生,如果有就工作,如果没有就休眠。主线程的RunLoop对象默认开启,其他线程默认不开启。
RunLoop与AutoreleasePool;
RunLoop处理的事件类型;
RunLoop的运行模式mode