1.什么是RunLoop
a) RunLoop解读
1) 运行循环
2) 在程序运行过程中循环做一些事情
b) 应用范畴
1) 定时器(Timer)
2) PerformSelector
3) GCD Async Main Queue
4) 事件响应、手势识别、界面刷新
5) 网络请求
6) AutoreleasePool
-
2.没有RunLoop
image
-
3.有RunLoop
image
4.RunLoop对象
a) iOS中有2套API来访问和使用RunLoop
1) Foundation:NSRunLoop
2) Core Foundation:CFRunLoopRef
b) NSRunLoop和CFRunLoopRef都代表着RunLoop对象
1) NSRunLoop是基于CFRunLoopRef的一层OC包装
c) CFRunLoopRef是开源的
1) https://opensource.apple.com/tarballs/CF/
image
5.RunLoop与线程
a) 每条线程都有唯一的一个与之对应的RunLoop对象
b) RunLoop保存在一个全局的Dictionary里,线程作为key,RunLoop作为value
c) 线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建
d) RunLoop会在线程结束时销毁
e) 主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop
6.RunLoop相关的类
a) Core Foundation中关于RunLoop的5个类
1) CFRunLoopRef
2) CFRunLoopModeRef
3) CFRunLoopSourceRef
4) CFRunLoopTimerRef
5) CFRunLoopObserverRef
image
image
image
b) CFRunLoopModeRef
1) CFRunLoopModeRef代表RunLoop的运行模式
2) 一个RunLoop包含若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer
3) RunLoop启动时只能选择其中一个Mode,作为currentMode
4) 如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入
不同组的Source0/Source1/Timer/Observer能分隔开来,互不影响
5) 如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出
6) 常见的2种Mode
6.1) kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行
6.2) UITrackingRunLoopMode:界面跟踪Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
7) NSRunLoopCommonModes解读
7.1) NSRunLoopCommonModes并不是一个真的模式,它只是一个标记,NSDefaultRunLoopMode、UITrackingRunLoopMode才是真正存在的模式
7.2) NSRunLoopCommonModes默认包括NSDefaultRunLoopMode、UITrackingRunLoopMode模式
7.3) 所以timer能在_commonModes数组中存放的模式下工作
c) CFRunLoopObserverRef
1) 用于监听Runloop的状态改变
image
2) 添加Observer监听RunLoop的所有状态
image
-
7.RunLoop的运行逻辑
image
a) Source0
1) 触摸事件处理
2) performSelector:onThread:
b) Source1
1) 基于Port的线程间通信
2) 系统事件捕捉
c) Timers
1) NSTimer
2) performSelector:withObject:afterDelay:
d) Observers
1) 用于监听RunLoop的状态
2) UI刷新(BeforeWaiting)
3) Autorelease pool(BeforeWaiting)
image
-
8.RunLoop休眠的实现原理
image
9.RunLoop在实际开中的应用
a) 控制线程生命周期(线程保活)
1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false) // C语言的多第3个参数:returnAfterSourceHandled,设置为true,代表执行完source后就会退出当前loop
2) [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] // OC形式的少一个所以需要外部变量来控制
b) 解决NSTimer在滑动时停止工作的问题
c) 监控应用卡顿
d) 性能优化
10.其它知识点总结
a) NSMutableArray & NSMutableSet区别
1) NSMutableArray : 有序的 通过index取数据
2) NSMutableSet : 无序的 只能随机取
b) bt(打印函数调用栈)
c) RunLoop切换模式是不会导致程序退出的
d) switch case里面定义变量,要用大括号包住case范围,明确告诉他变量的作用域(C语言的知识)
e) 线程和控制器的互相强引用问题SEL的问题
f) gcd很多东西不依赖Runloop
g) Runloop的run方法的解读为什么无法停止?
1) 它专门用于开启一个永不销毁的线程
// [[NSRunLoop currentRunLoop] run];
/*
it runs the receiver in the NSDefaultRunLoopMode by repeatedly invoking runMode:beforeDate:.
In other words, this method effectively begins an infinite loop that processes data from the run loop’s input sources and timers
*/
h) waitUntilDone设置相关
{
[self performSelector:@selector(stopThread) onThread:self.thread withObject:nil waitUntilDone:YES];
NSLog(@"%s %@", __func__, [NSThread currentThread]);
}
1) waitUntilDone设置为YES : 代表子线程的代码执行完毕后,这个方法才会往下走即stopThread方法走完,才会走NSLog
2) waitUntilDone设置为NO : 代表该行方法执行完,就执行NSLog & stopThread互不影响
i) CFRunLoopGetCurrent()
1) 你当前在那个线程调用的获取线程的方法获取的就是那个线程
j) 局部变量初始化
1) CFRunLoopSourceContext context = {0}; 创建上下文(要初始化一下结构体)
网友评论