iOS|iOS RunLoop(1)RunLoop简介

iOS RunLoop(1)RunLoop简介
iOS RunLoop(2)RunLoop相关类
iOS RunLoop(3)RunLoop原理
iOS RunLoop(4)RunLoop实战应用
RunLoop简介 什么是RunLoop?
可以理解为字面意思:Run表示运行,Loop表示循环。结合在一起就是运行的循环的意思。哈哈,我更愿意翻译为『跑圈』。直观理解就像是不停的跑圈。
RunLoop实际上是一个对象,这个对象在循环中用来处理程序运行过程中出现的各种事件(比如说触摸事件、UI刷新事件、定时器事件、Selector事件),从而保持程序的持续运行;而且在没有事件处理的时候,会进入睡眠模式,从而节省CPU资源,提高程序性能。
RunLoop和线程
首先,iOS 开发中能遇到两个线程对象: pthread_t 和 NSThread。过去苹果有份文档标明了 NSThread 只是 pthread_t 的封装,但那份文档已经失效了,现在它们也有可能都是直接包装自最底层的 mach thread。苹果并没有提供这两个对象相互转换的接口,但不管怎么样,可以肯定的是 pthread_t 和 NSThread 是一一对应的。比如,你可以通过 pthread_main_thread_np() 或 [NSThread mainThread] 来获取主线程;也可以通过 pthread_self() 或 [NSThread currentThread] 来获取当前线程。CFRunLoop 是基于 pthread 来管理的。
【iOS|iOS RunLoop(1)RunLoop简介】苹果不允许直接创建 RunLoop,它只提供了两个自动获取的函数:CFRunLoopGetMain() 和 CFRunLoopGetCurrent()。
一条线程对应一个RunLoop对象,每条线程都有唯一一个与之对应的RunLoop对象。
我们只能在当前线程中操作当前线程的RunLoop,而不能去操作其他线程的RunLoop。
RunLoop对象在第一次获取RunLoop时创建,销毁则是在线程结束的时候。
主线程的RunLoop对象系统自动帮助我们创建好了(原理如下),而子线程的RunLoop对象需要我们主动创建。
默认情况下主线程的RunLoop原理
我们在启动一个iOS程序的时候,系统会调用创建项目时自动生成的main.m的文件。main.m文件如下所示:

int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }

其中UIApplicationMain函数内部帮我们开启了主线程的RunLoop,UIApplicationMain内部拥有一个无线循环的代码。上边的代码中开启RunLoop的过程可以简单的理解为如下代码:
int main(int argc, char * argv[]) { BOOL running = YES; do { // 执行各种任务,处理各种事件 // ...... } while (running); return 0; }

从上边可看出,程序一直在do-while循环中执行,所以UIApplicationMain函数一直没有返回,我们在运行程序之后程序不会马上退出,会保持持续运行状态。


下图是苹果官方给出的RunLoop模型图。 iOS|iOS RunLoop(1)RunLoop简介
文章图片
runLoop.jpg 从上图中可以看出,RunLoop就是线程中的一个循环,RunLoop在循环中会不断检测,通过Input sources(输入源)和Timer sources(定时源)两种来源等待接受事件;然后对接受到的事件通知线程进行处理,并在没有事件的时候进行休息。
文章来源:
https://www.jianshu.com/p/d260d18dd551
https://blog.ibireme.com/2015/05/18/runloop/

    推荐阅读