iOS面试题-RunLoop
什么是RunLoop?
运行循环,在程序运行过程中循环做一些事情,如果没有Runloop程序执行完毕就会立即退出,如果有Runloop程序会一直运行,并且时时刻刻在等待用户的输入操作。RunLoop可以在需要的时候自己跑起来运行,在没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。
RunLoop的内部实现逻辑
RunLoop内部是一个do while循环。
RunLoop的基本作用
1.保持程序持续运行;
2.处理App中的各种事件;
3.节省CPU资源,提高程序性能
RunLoop和线程间的关系
1.每条线程都有唯一的一个与之对应的RunLoop对象
2.主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建
3.RunLoop在第一次获取时创建,在线程结束时销毁
线程和 RunLoop 之间是一一对应的,其关系是保存在一个 Dictionary 里。所以我们创建子线程RunLoop时,只需在子线程中获取当前线程的RunLoop对象即可[NSRunLoop currentRunLoop];如果不获取,那子线程就不会创建与之相关联的RunLoop,并且只能在一个线程的内部获取其 RunLoop[NSRunLoop currentRunLoop];方法调用时,会先看一下字典里有没有存子线程相对用的RunLoop,如果有则直接返回RunLoop,如果没有则会创建一个,并将与之对应的子线程存入字典中。
RunLoop运行模式
一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source、Timer、Observer 每次RunLoop启动时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode 如果需要切换Mode,只能退出RunLoop,再重新指定一个Mode进入,这样做主要是为了分隔开不同组的Source、Timer、Observer,让其互不影响。如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出。
RunLoop事件源
Source0:非基于Port的 用于用户主动触发的事件(点击button 或点击屏幕)
Source1:基于Port的 通过内核和其他线程相互发送消息(与内核相关)
Runloop 是怎么响应用户操作的, 具体流程是什么样的
1.通知观察者 run loop 已经启动
2.通知观察者将要开始处理Timer事件
3.通知观察者将要处理非基于端口的Source0
4.启动准备好的Souecr0
5.如果基于端口的源Source1准备好并处于等待状态,立即启动:并进入步骤9
6.通知观察者线程进入休眠
7.将线程置于休眠直到任一下面的事件发生
(1)某一事件到达基于端口的源
(2)定时器启动
(3)Run loop 设置的时间已经超时
(4)run loop 被显式唤醒
8.通知观察者线程将被唤醒
9.处理未处理的事件,跳回2
(1)如果用户定义的定时器启动,处理定时器事件并重启 run loop。进入步骤 2
(2)如果输入源启动,传递相应的消息
(3)如果 run loop 被显式唤醒而且时间还没超时,重启 run loop。进入步骤 2
10.通知观察者run loop 结束
RunLoop退出
1.主线程销毁RunLoop退出Mode中有一些Timer 、Source、 Observer,这些保证Mode不2.为空时保证RunLoop没有空转并且是在运行的,当Mode中为空的时候,RunLoop会立刻3.退出我们在启动RunLoop的时候可以设置什么时候停止。
RunLoop应用
1.常住线程:当子线程中的任务执行完毕之后就被销毁了,如果我们需要开启一个子线程,在程序运行过程中永远存在,这时就要用到常驻线程:给子线程开启一个RunLoop
2.自动释放池:RunLoop内部有一个自动释放池,当RunLoop开启时,就会自动创建一个自动释放池,当RunLoop在休息之前会释放掉自动释放池的东西,然后重新创建一个新的空的自动释放池,当RunLoop被唤醒重新开始跑圈时,Timer,Source等新的事件就会放到新的自动释放池中,当RunLoop退出的时候也会被释放。