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; // 定时器
 ...
};
  1. CFRunLoopModeRef代表RunLoop的运行模式
  2. 一个Runloop包含多个Mode,每个Mode包含多个source0,source1,observer,timer
  3. Runloop启动时只能选择其中一个Mode作为当前Mode
  4. 如果需要切换Mode,只能退出当前loop,在重新选择Mode进入
  5. 如果一个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 // 所有状态
    };
作者:取个有意思的昵称

%s 个评论

要回复文章请先登录注册