缘由: 或许也许大概是因为写业务太无聊了,决定和新来的同事一起搞点事情。最后我们决定根据官方文档整理一下 CFRunLoop 的相关知识(后续待定...),在阅读过程中我决定尝试翻译一下,话不多说,这就开始。
CFRunLoop 对象负责监测输入源并将它们作为"任务"加入队列,并且对队列中的任务进行分发控制。
输入源包括输入设备、网络任务、周期性或延迟性事件以及异步回调。runLoop 可以监监测3种对象:CFRunLoopSource、CFRunLoopTimer、CFRunLoopObserver。你必须通过
CFRunLoopAddSource()
、CFRunLoopAddTimer()
或CFRunLoopAddObserver()
方法将他们加入 runLoop 来监听它们在队列中执行时的回掉,你能够将它们移除 runLoop 从而放弃监听。这些对象被加入 runLoop 时必须关联一个或者多个 CFRunLoopMode。runLoop 每次只会运行在一个 mode(模式) 中,且队列中只关联当前 mode 的事件,runLoop 默认运行在
defaultMode
(负责线程日常空闲的任务分配),系统也定义了一些其他的 mode 来对其他的任务进行分发(例如监听 UIScrollerView 的滑动在trackingMode
: 其实是 NSRunLoop 中的 mode),由于 runLoop 的 mode 本质是规定一个字符串常量座位唯一标识符,你也可以自定义一个 mode 来控制任务队列。Core Foundation 中还定义了一个特别的 mode: commonModes。他表示 mode 的一个集合(包含当前 runLoop 中的 mode ,每一个 runLoop 都有自己的 commonModes 并且默认含有
defaultMode
),调用CFRunLoopAddCommonMode()
方法可以向 commonModes 中添加 mode。一个线程仅有唯一确定的一个runLoop,你无法更改线程所对应的 runLoop,Core Foundation 会在你需要的时候自动创建 runLoop,你只能通过
CFRunLoopGetCurrent()
方法来获得当前 runLoop。CFRunLoopRun()
使其在defaultMode
运行、CFRunLoopRunInMode()
则可以指定 mode 运行,CFRunLoopStop()
使 runLoop 停止。只要 runLoop 队列中有一个任务,该 runLoop 就能够运行。runLoop 能够递归调用。你能够在任意 runLoop 执行时使用
CFRunLoopRun()
或CFRunLoopRunInMode()
在当前线程创建一个子 runLoop 然后在当前线程调用栈中激活子 runLoop。并且你可以不受限制的让它以任何 mode 运行(只要是你可以获得到的 mode)。Cocoa Touch 基于 CFRunLoop 实现了一个高等的事件循环机制 (NSRunLoop)。我们实际开发时可以向 NSRunLoop 实例中添加 sources、timers 以及 observers 并且指定 mode,他们就会成为应用的事件循环中的一部分。
getCFRunLoop()
方法可获得当前 runLoop 相应的 CFRunLoop 类型。
ps: 第一次翻译,表示看的懂不代表能够流畅的用英文翻译出来。如有错误,谢谢指正。
下节介绍 CFRunLoop 中的 API...