iOScodesRunloop

iOS RunLoop(1)RunLoop简介

2018-07-02  本文已影响157人  奔跑吧小蚂蚁

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 来管理的。

苹果不允许直接创建 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模型图。 runLoop.jpg

从上图中可以看出,RunLoop就是线程中的一个循环,RunLoop在循环中会不断检测,通过Input sources(输入源)和Timer sources(定时源)两种来源等待接受事件;然后对接受到的事件通知线程进行处理,并在没有事件的时候进行休息。

文章来源:
https://www.jianshu.com/p/d260d18dd551
https://blog.ibireme.com/2015/05/18/runloop/

上一篇 下一篇

猜你喜欢

热点阅读