28 RunLoop

1字面意思:运行循环、跑圈,内部其实就是do-while循环,在这个循环内部不断地处理各种事物,NSRunloop就是消息循环,每一个线程内部都有一个消息循环,只有主线程的消息循环默认开启,子线程的消息循环默认不开启 ,如果不主动获取Runloop,子线程内部就不会创建RunLoop,生命周期是在第一次获取时创建,在线程结束时销毁,runloop对象是利用字典来进行存储,而且key是对应的线程,value为该线程对应的Runloop.

2运行循环的目的:

a保证应用程序不退出,持续运行,内部是do-while循环,在这个循环内部不断处理各种事件

b处理app中的各种事件(触摸事件、定时器事件、selector事件、选择器performSelector)接受输入事件来自两种不同的来源:输入源和定时源,输入源(键盘,鼠标,NSPort,NSConnection)input source和定时源timer source.

performSelector:onThread:也可以作为输入事件

(NSConnection非常依赖线程里的消息循环)

c没有事件发生,会让程序进入休眠状态,节省CPU资源,提高程序性能

Runloop是程序一直存在并不断处理事件的原因,main函数中的RunLoop,在UIApplication函数内部启动一个Runloop,该函数返回一个int类型的值,默认启动的Runloop是跟主线程相关的

3ios开发中,有两套api访问Runloop,foundation框架(NSRunloop),core foundation框架(CFRunloopRef),都代表Runloop对象,等价的可以互相转换,

4获取Runloop对象,

NSRunLoop *runloop1 = NSRunloop currentRunLoop];

CFRunLoop *runloop2 = CFRunLoopGetCurrent();

获取主Runloop

NSRunLoop *runloop1 = NSRunLoop mainRunLoop];

CFRunLoop *runloop2 = CFRunLoopGetMain();

5基本使用:每次Runloop启动时,只能指定其中一个Mode,这个Mode被称作CurrentMode,如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入,这样做的主要目的是为了隔离不同Mode中的Source、Timer、Observer,让其互不影响

消息循环处理输入事件时,必须消息循环的模式和输入源的运行模式相互匹配,输入源对应的事件才能被消息循环检测到.常用的模式有,NSRunloopCommonModes,NSDefaultRunloopModes,UITrackingRunLoopModes

a NSTimer必须添加到runloop中才会工作,且其工作受到runloop运行模式的影响

b runloop启动之后会选择一种运行模式,在执行执行会先检查运行模式内部是否有source和timers,如果一个sourc或者是一个timer都没有那么runlooop启动之后就立刻退出了。

c runlooop的source有两种分类方法

按照以前的分类方法可以分为: 基于端口的  自定义的  performSelector事件

按照函数调用栈来划分:  source0  soucrce1

使用:

a 开启NSTimer,控制定时器在特定模式下执行

bPerformSelector OnThread:控制线程执行不同的任务

c自动释放池(可通过Observer监听RunLoop的状态)

第一次创建:进入runloop的时候

最后一次释放:runloop退出的时候

其它创建和释放:当runloop即将休眠的时候会把之前的自动释放池释放,然后重新创建一个新的释放池

d常驻线程:让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件

常驻线程实现:

主线程对应的runloop默认已经创建好了,但是子线程对应的runloop需要手动创建

子线程对应的runloop还需要手动的开启,否则该runloop一创建出来就退出;在开启前要先添加事件,否则也会退出。

保证mode里面有事件,不让runloop立刻退出

可以往runloop中添加source和timer,但是添加observer是没有作用的

你可能感兴趣的:(28 RunLoop)