美文网首页
2018-05-26

2018-05-26

作者: 阿什不可思 | 来源:发表于2018-05-26 11:55 被阅读0次

NSRunloop

1. runloop的定义

RunLoop实际上是一个对象,这个对象在循环中用来处理程序运行过程中出现的各种事件

(比如说触摸事件、UI刷新事件、定时器事件、Selector事件),

从而保持程序的持续运行;而且在没有事件处理的时候,会进入睡眠模式,从而节省CPU资源,提高程序性能。

2. runloop与线程

RunLoop和线程是息息相关的,我们知道线程的作用是用来执行特定的一个或多个任务,但是在默认情况下,线程执行完之后就会退出,就不能再执行任务了。这时我们就需要采用一种方式来让线程能够处理任务,并不退出。所以,我们就有了RunLoop。

一条线程对应一个RunLoop对象,每条线程都有唯一一个与之对应的RunLoop对象。

我们只能在当前线程中操作当前线程的RunLoop,而不能去操作其他线程的RunLoop。

RunLoop对象在第一次获取RunLoop时创建,销毁则是在线程结束的时候。

主线程的RunLoop对象系统自动帮助我们创建好了(原理如下),而子线程的RunLoop对象需要我们主动创建。

3. 默认情况下主线程的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模型图

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

4. RunLoop相关类

下面我们来了解一下Core Foundation框架下关于RunLoop的5个类,只有弄懂这几个类的含义,我们才能深入了解RunLoop运行机制。

CFRunLoopRef:代表RunLoop的对象

CFRunLoopModeRef:RunLoop的运行模式

CFRunLoopSourceRef:就是RunLoop模型图中提到的输入源/事件源

CFRunLoopTimerRef:就是RunLoop模型图中提到的定时源

CFRunLoopObserverRef:观察者,能够监听RunLoop的状态改变

CFRunLoopRef就是Core Foundation框架下RunLoop对象类。我们可通过以下方式来获取RunLoop对象:

Core Foundation

CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象

CFRunLoopGetMain(); // 获得主线程的RunLoop对象

当然,在Foundation框架下获取RunLoop对象类的方法如下:

Foundation

[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象

[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象

2.2 CFRunLoopModeRef

runloop的五个Mode

系统默认定义了多种运行模式(CFRunLoopModeRef),如下:

kCFRunLoopDefaultMode:App的默认运行模式,通常主线程是在这个运行模式下运行

UITrackingRunLoopMode:跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响)

UIInitializationRunLoopMode:在刚启动App时第进入的第一个 Mode,启动完成后就不再使用

GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到

kCFRunLoopCommonModes:伪模式,不是一种真正的运行模式(后边会用到)

相关文章

网友评论

      本文标题:2018-05-26

      本文链接:https://www.haomeiwen.com/subject/ozcmjftx.html