Runloop 小记01
Runloop 即运行循环
启动一个app,默认在主线程创建一个Runloop,保持程序持续运行,不会程序马上退出,处理app中的各种事件(触摸事件,定时器事件等),节省CPU资源,提高程序性能(在没有事件时休眠,需要处理事件时激活)
应用范畴: 定时器,performselector,GCD,事件响应,界面刷新,网络请求,AutoreleasePool
NSRunLoop *mainRunLoop = [NSRunLoop mainRunLoop]; // 获取主线程的Runloop对象
NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; // 获取当前Runloop对象
Runloop与线程
- 每条线程都有一个与之对应的Runloop对象
- Runloop保持在一个全局的Dictionary里,线程为key,Runloop为value
- 线程刚创建时并没有Runloop对象,Runloop在第一次获取它时创建
- Runloop在线程结束时销毁
- 主线程的Runloop自动创建,子线程默认没有开启Runloop(除非在子线程里创建一个Runloop)
Runloop的五个类
CFRunLoopRef CFRunLoopModeRef CFRunLoopSourceRef CFRunLoopTimerRef CFRunLoopObserverRef
每个CFRunLoopRef包含多个CFRunLoopModeRef,每个CFRunLoopModeRef包含多个CFRunLoopSourceRef,CFRunLoopTimerRef,CFRunLoopObserverRef
*CFRunLoopRef
struct __CFRunLoop {
CFMutableSetRef _commonModes; //
CFMutableSetRef _commonModeItems; //
CFRunLoopModeRef _currentMode; // 当前Mode模式
CFMutableSetRef _modes; // 包含多个CFRunLoopModeRef的集合
...
};
struct __CFRunLoopMode {
CFStringRef _name; // Mode Name, 例如 @"kCFRunLoopDefaultMode"
CFMutableSetRef _sources0; // 点击,触摸等处理
CFMutableSetRef _sources1; // 不同线程间port通信;点击触摸等事件的捕捉,在包装成source0进行处理
CFMutableArrayRef _observers; // 监听器,UI刷新(通过监听界面在进入runloop休眠前刷新),autorelease
CFMutableArrayRef _timers; // 定时器
...
};
- CFRunLoopModeRef代表RunLoop的运行模式
- 一个Runloop包含多个Mode,每个Mode包含多个source0,source1,observer,timer
- Runloop启动时只能选择其中一个Mode作为当前Mode
- 如果需要切换Mode,只能退出当前loop,在重新选择Mode进入
- 如果一个runloop里面没有任何sourec,observer,timer,立即退出
- CFRunLoopModeRef 主要的两种Mode模式
NSDefaultRunLoopMode App默认的Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode 界面跟踪Mode,比如ScrollView触摸滑动,保证界面滑动不受其他Mode影响
- Runloop的几种状态
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { kCFRunLoopEntry = (1UL << 0), // 即将进入Loop kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理 Timer kCFRunLoopBeforeSources = (1UL << 2), // 即将处理 Source kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠 kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒 kCFRunLoopExit = (1UL << 7), // 即将退出Loop kCFRunLoopAllActivities // 所有状态 };