Runloop的总结

2019-02-20  本文已影响1人  不想重复造轮子

Runloop

RunLoop内部逻辑

  1. 通知 Observer: 即将进入 Loop --> Observer
  2. 通知 Observer: 即将要处理 Source()
  3. 通知 Observer: 将要处理 Source0
  4. 处理理 Source0
  5. 若有 Source1, 跳到 9
  6. 通知 Observer: 线程即将休眠
  7. 休眠等待唤醒 (Source0 (port) Timer 外部手动唤醒)
  8. 通知 Observer: 线程刚被唤醒
  9. 处理唤醒时 收到的消息, 跳至 2
  10. 通知 Observer 即将退出 Loop

Runloop & 线程

  1. 每个线程,包括程序的主线程 都有与之对应的 run loop对象.
  2. runloops 是线程的基础架构部分
  3. 主线程的run loop 是默认启动的.
  4. 在 main()函数里
int main(int argc, char * argv[]) {
    @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

  1. 对于其他线程来说 run loop默认是没有启动的, 如果需要更多的线程交互则可以手动配置和启动,若线程只是
    去执行一个长时间的已确定的任务则不需要.

  2. 在任何一个 Cocoa程序的线程中, 都可以通过:

  [NSRunLoop currentRunLoop]

来获取当前线程的 run loop.

  1. 一个Runloop包含若干个 Mode 每个Mode 又包含若干个 Source/Timer/Observer. 每次调用 Runloop 的主函
    数时,只能指定其中⼀个Mode. 切换Mode 的时候需要退出 Loop, 再重新指定⼀个 Mode 进入. 为了分隔开不
    同组的 Source/Timer/Observer, 让其相互不影响.

  2. CFRunLoopSourceRef

  1. CFRunLoopTimerRef
  1. CFRunLoopObserverRef
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 = 0x0FFFFFFFU
};

  1. Source/Timer/Observer 被统称为 mode item, 一个 item可以被同时加入多个 mode. 但一个 item被重复加入
    同一个mode时是不会有效果的,若一个 Mode中一个 item 都没有 则RunLoop会直接推出.不进入循环.

  2. 系统定义的RunLoop模式有五种,最常用的有三种,如下所示:

NSRunloop & CFRunlloRef

RunLoop应⽤用场景

上一篇 下一篇

猜你喜欢

热点阅读