iOS runloop与多线程

一、RunLoop是什么?

事件循环,绝对不止是死循环这么简单的一个回答。实质上就是runloop内部状态的转换。

1.用户态:应用程序都是在用户态,平时开发用到的api等都是用户态的操作

2.内核态:系统调用,牵涉到操作系统,底层内核相关的指令。

runloop实际上是计算机内部进行的资源调度操作。

iOS中的runloop就是循环来处理程序运行过程中出现的各种事件(比如说触摸事件、UI刷新事件、定时器事件、Selector事件),从而保持程序的持续运行,而在没有任何任务处理时,会让线程休眠,从而节省 CPU 资源,提高程序性能。

iOS中的runloop是用来处理事件的循环,NSRunloop是基于CFRunloop的封装,是线程不安全的;CFRunloop是一套C接口,是线程安全的。

二、runloop有哪些使用场景?

1,检测crash,crash的起死回生;

2,线程的耦合;

3,监测APP的卡顿;

4,线程保活(让线程长时间存活,而不被自动销毁掉)等。

三,runloop的组成?

CFRunLoopRef //runloop对象包含以下内容:

CFRunLoopModeRef//运行模式

CFRunLoopObserverRef

CFRunLoopTimerRef

CFRunLoopSourceRef//sources源(事件源)

sources包含source0和source1,

source1:是基于Port的系统内核事件,主动唤醒,是基于字典的(key?-value?)。

source0:是非基于Port的,是用户事件,不能主动触发,需要手动唤醒(weakup),事件源一般存放在数组中,

runloop要想正常启动,需要添加一个source源,或者一个timer,有三种当方式:addPort,addTimer,CFRunloopAddSource。

四,runloop与线程的关系?

线程与runloop是一一对应关系,由runloop的foundation的CFRunloopGet0源码可以看出,线程与runloop是以键值对的形式存储,key值存当前线程,value值存与线程对应的runloop。

1,(线程与runloop是一一对应关系)一条线程对应一个RunLoop对象,每条线程都有唯一一个与之对应的 RunLoop 对象。

RunLoop 并不保证线程安全。我们只能在当前线程内部操作当前线程的 RunLoop 对象,而不能在当前线程内部去操作其他线程的 RunLoop 对象方法。

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

3,主线程的 RunLoop 对象系统自动帮助我们创建好了(原理如 1.3 所示),而子线程的 RunLoop对象需要我们主动创建和维护。

五,主线程需要保活吗?

子线城需要事件源,线程才能保活。

主线程不需要,(值为1)底层源码分析得。

六,runloop如何启动?,启动方式有哪些?

三种方式:run,runUntilDate,RunMode:beforDate。

前两种底层其实是无限循环调用RunMode方法,使用后runloop不会停止,故一般使用第三种,启动一次runloop,调用停止runloop方法后,便可结束runloop。

七,如何停止runloop?

CFRunLoopStop

若用strong修饰thread,需将thread设置为nil。

ViewController释放后,也需要需将thread设置为nil,防止内存泄露。

八,runloop原理?

runloop原理


在每次运行开启RunLoop的时候,所在线程的RunLoop会自动处理之前未处理的事件,并且通知相关的观察者。

具体的顺序如下:

通知观察者RunLoop已经启动

通知观察者即将要开始的定时器

通知观察者任何即将启动的非基于端口的源

启动任何准备好的非基于端口的源

如果基于端口的源准备好并处于等待状态,立即启动;并进入步骤9

通知观察者线程进入休眠状态

将线程置于休眠知道任一下面的事件发生:

某一事件到达基于端口的源

定时器启动

RunLoop设置的时间已经超时

RunLoop被显示唤醒

通知观察者线程将被唤醒

处理未处理的事件

如果用户定义的定时器启动,处理定时器事件并重启RunLoop。进入步骤2

如果输入源启动,传递相应的消息

如果RunLoop被显示唤醒而且时间还没超时,重启RunLoop。进入步骤2

通知观察者RunLoop结束。

你可能感兴趣的:(iOS runloop与多线程)