深入浅出Runloop

2019-08-01  本文已影响0人  海牛骑士

书上得来终觉浅、绝知此事要躬行。本文参考来源:http://mrpeak.cn/blog/ios-runloop/

一.Runloop 简介

什么是runloop ,简单来说、就是一个 do while 死循环、每次loop 都会执行下面的事情,当没有任务的时候 就会进入休眠。

{
 performmask()  //执行任务
 callout_to_observer()  //通知外部
 sleep() //休眠
}

Performtask()

每次loop都会都会执行若干个task,在我们runloop执行的任务又有哪些呢,总结下来有下面5种

callout_to_observer

主要是来通知外部观察者当前runloop执行了那些任务,当前runloop处于那种状态。有如下三种方式 以及相对应调用的函数。

__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);

这是上述五种执行任务方式中 ,两种可以注册 observer 的,其他几个都不支持,mainQueue,source1,block 都不行。所以理论上,是没有办法准确测量各个任务执行的时长的。

DoObserver-Activity是runloop 用来通知外部自己当前处于那个状态。根据源码runloop有如下几种状态

typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << 0),//开始进入某个Model
    kCFRunLoopBeforeTimers = (1UL << 1),
    kCFRunLoopBeforeSources = (1UL << 2),
    kCFRunLoopBeforeWaiting = (1UL << 5),//开始休眠之前
    kCFRunLoopAfterWaiting = (1UL << 6),//休眠中恢复
    kCFRunLoopExit = (1UL << 7),//退出切换model
    kCFRunLoopAllActivities = 0x0FFFFFFFU
};

sleep()

没有任务就休眠,有任务就执行。

Runloop 完整执行流程

根据RunLoop简介 我们已经将RunLoop 细分为三类,但是RunLoop并非是按上述划分顺序执行的,而他们是相互交错运行的。

完整流程图 .png

根据上面的流程图 呈现了 五种任务执行和六种通知外部函数的执行过程。

RunLoop Model

RunLoopModel 非常重要,核心点。

在一个程序运行中有一个主线程的RunLoop 和很多个子线程的Runloop。主线程的runLoop默认是开启状态,在我们的RunLoop里面又存在多个RunLoopModel,每个Model 都在执行上面描述的过程。在上面的任务和外部通知中大部分函数是和我们Model进行绑定执行的。RunLoop的结构源码如下

struct __CFRunLoopMode {
    ...
    CFStringRef _name;
    CFMutableSetRef _sources0;
    CFMutableSetRef _sources1;
    CFMutableArrayRef _observers;
    CFMutableArrayRef _timers;
    CFMutableDictionaryRef _portToV1SourceMap;
    CFIndex _observerMask;
    ...
};

RunLoopModel 的种类分为common和private两大类共五种。
公共的

私有的

我们常用的也就是公共里面的两种 kCFRunLoopDefaultMode 和 UITrackingRunLoopMode

RunLoop的作用

RunLoop和线程的关系

上一篇 下一篇

猜你喜欢

热点阅读