参考
https://ke.qq.com/course/314526
RunLoop基本作用
1.保持程序的持续运行。
2.处理App中的各种事件,如触摸事件、定时器事件等。
3.节省CPU资源,提高程序性能:该做事时做事,该休息时休息。
RunLoop对象
在iOS中RunLoop有两套API来使用,一套开源的C语言的CFRunLoopRef,一套OC的NSRunLoop,NSRunLoop是基于 CFRunLoopRef的一层OC包装。
获取RunLoop对象:
1.当前线程RunLoop对象
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
CFRunLoopRef runloop = CFRunLoopGetCurrent();
2.主线程RunLoop对象
NSRunLoop *runloop = [NSRunLoop mainRunLoop];
CFRunLoopRef runloop = CFRunLoopGetMain();
RunLoop与线程的关系
1.每条线程都有唯一的一个RunLoop对象。
2.RunLoop保存在一个全局的 Dictionary里,线程作为key, RunLoop作为 value。
3.线程刚创建时并没有 RunLoop对象, RunLoop会在第一次获取它时创建。
4.RunLoop会在线程结束时销毁。
5.主线程的 RunLoop已经自动获取,子线程默认没有开启 Runloop。
RunLoop详解
1.一个 Runloop包含若干个Mode,每个Mode又包含若干个 Source0/ Source1/ Timer/ Observer,切换mode不会导致程序退出。
2.Runloop启动时只能选择其中一个Mode,作为 currentMode。
3.如果需要切换Mode,只能退出当前Mode,再重新选择一个Mode进入,不同组的 Source0/ Source1/ Timer/ Observer能分隔开来,互不影响。
4.如果Mode里没有任何 Source0/ Source/ Timer/ Observer,Runloop会立马退出。
Mode详解
Mode内部Source0/ Source1/ Timer/ Observer解析
1> Source0:
触摸事件处理
2> Source1:
基于Port的线程间通信,系统事件捕捉,点击事件由Source1捕捉,分发给Source0处理
3> Timers:
定时器NSTimer,延时操作performselector: withobject: afterdelay:
4> Observers:
用于监听 Runloop的状态,UI刷新,自动释放池Autorelease pool
RunLoop运行逻辑
内部不断的循环处理block,source,Timer等,处理完成就休眠,被消息唤醒就继续处理。
RunLoop应用场景
1.控制线程生命周期
2.解决定时器在滑动时停止工作的问题
3.监控应用卡顿
4.性能优化等
// 演示RunLoop应用场景之一
// 解决定时器在滑动时停止工作的问题
__block NSInteger count = 0;
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"%ld",(long)++count);
}];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
补充
1.如果需要打印Runloop的内存地址,那么CFRunLoopRef打印的地址值才是正确的地址值,NSRunLoop打印的Runloop地址值是进行过包装的。
2.RunLoop的休眠是内核休眠,不消耗CPU的资源。
3.本文如有侵犯隐私或其他请联系我,我将在第一时间整改或删除。