参考:http://www.cnblogs.com/superYou/p/4645168.html
runloop面试题
1.什么是RunLoop?
从字面意思看:运行循环、跑圈
其实它内部就是do-while循环,在这个循环内部不断地处理各种任务(比如Source、Timer、Observer)
一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop得手动启动(调用run方法)
RunLoop只能选择一个Model启动,如果当期Model中没有任何Source(Source0、Source1)、Timer,那么久直接退出RunLoop
2.自动释放池什么时候释放?
通过Observer监听RunLoop的状态
3.在开发中如何使用RunLoop?什么应用场景?
开启一个常驻线程(让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件)例如:在子线程开启一个定时器;在子线程进行一些长期监控
可以控制定时器在特定模式下执行
可以让某些事件行为在特定模式下执行
可以添加Observe监听RunLoop的状态,比如点击事件的处理(在所有点击事件之前做一些事情)
1.Runloop基础知识
- 1.1 字面意思
a 运行循环
b 跑圈
- 1.2 基本作用(作用重大)
a 保持程序的持续运行(ios程序为什么能一直活着不会死)
b 处理app中的各种事件(比如触摸事件、定时器事件【NSTimer】、selector事件【选择器·performSelector···】)
c 节省CPU资源,提高程序性能,有事情就做事情,没事情就休息
- 1.3 重要说明
(1)如果没有Runloop,那么程序一启动就会退出,什么事情都做不了。
(2)如果有了Runloop,那么相当于在内部有一个死循环,能够保证程序的持续运行
(2)main函数中的Runloop
a 在UIApplication函数内部就启动了一个Runloop
该函数返回一个int类型的值
b 这个默认启动的Runloop是跟主线程相关联的
- 1.4 Runloop对象
(1)在iOS开发中有两套api来访问Runloop
a.foundation框架【NSRunloop】
b.core foundation框架【CFRunloopRef】
(2)NSRunLoop和CFRunLoopRef都代表着RunLoop对象,它们是等价的,可以互相转换
(3)NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)
- 1.5 Runloop参考资料
```objc
(1)苹果官方文档
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
(2)CFRunLoopRef开源代码下载地址:
http://opensource.apple.com/source/CF/CF-1151.16/
```
- 1.6 Runloop与线程
1.Runloop和线程的关系:一个Runloop对应着一条唯一的线程
问题:如何让子线程不死
回答:给这条子线程开启一个Runloop
2.Runloop的创建:主线程Runloop已经创建好了,子线程的runloop需要手动创建
3.Runloop的生命周期:在第一次获取时创建,在线程结束时销毁
- 1.7 获得Runloop对象
```objc
1.获得当前Runloop对象
//01 NSRunloop
NSRunLoop * runloop1 = [NSRunLoop currentRunLoop];
//02 CFRunLoopRef
CFRunLoopRef runloop2 = CFRunLoopGetCurrent();
2.拿到当前应用程序的主Runloop(主线程对应的Runloop)
//01 NSRunloop
NSRunLoop * runloop1 = [NSRunLoop mainRunLoop];
//02 CFRunLoopRef
CFRunLoopRef runloop2 = CFRunLoopGetMain();
3.注意点:开一个子线程创建runloop,不是通过alloc init方法创建,而是直接通过调用currentRunLoop方法来创建,它本身是一个懒加载的。
4.在子线程中,如果不主动获取Runloop的话,那么子线程内部是不会创建Runloop的。可以下载CFRunloopRef的源码,搜索_CFRunloopGet0,查看代码。
5.Runloop对象是利用字典来进行存储,而且key是对应的线程Value为该线程对应的Runloop。
2.Runloop应用
1)NSTimer
2)ImageView显示:控制方法在特定的模式下可用
3)PerformSelector
4)常驻线程:在子线程中开启一个runloop
5)自动释放池
第一次创建:进入runloop的时候
最后一次释放:runloop退出的时候
其它创建和释放:当runloop即将休眠的时候会把之前的自动释放池释放,然后重新创建一个新的释放池