CFRunLoop -- API

  • 获取 Run Loop 的方法
/**
 *返回当前线程的runloop
 *每一个线程有且仅有一个与之关联的runloop 
 */ 
func CFRunLoopGetCurrent() -> CFRunLoop!

// 返回主线程的runloop
func CFRunLoopGetMain() -> CFRunLoop!
  • 运行以及停止 Run Loop 的方法
/**
 *  在默认模式下运行当前线程的runloop。通过执行 CFRunLoopStop(_:)或者从defaultMode移除所有的sources和timers,来停止runloop停止。
 * runloop能够递归运行,你可以通过这个方法在一个runloop调用里创建一个嵌套的runloop并且加入当前线程的调用栈
 */
func CFRunLoopRun()

/**
 *  在指定的模式下运行当前线程的runloop, runloop能够被递归调用,你能够在当前线程的调用栈激活子runloop。你能在你可使用的模式激活任意runloop。
 *  @parma   mode: 指定模式,可以是任意CFString类型的字符串(即:可以隐式创建一个模式)但是一个模式必须至少包括一个source或者timer才能运行。不必具体说明 runloop运行在commonModes中的哪个mode,runloop会在一个特定的模式运行。 只有当你注册一个observer时希望observer运行在不止一个模式的时候需要具体说明
 *  @parma   seconds: 指定runloop运行时间. 如果为0,在runloop返回前会被执行一次;忽略returnAfterSourceHandled的值, 如果有多个sources或者timers已准备好立刻运行,仅有一个能被执行(除非sources中有source0)。
 *  @parma   returnAfterSourceHandled: 判断运行了一个source之后runloop是否退出。如果为false,runloop继续执行事件直到第二次调遣结束
 *  @return  runloop退出的原因:
             kCFRunLoopRunFinished:runloop中已经没有sources和timers
             kCFRunLoopRunStopped:runloop通过 CFRunLoopStop(_:)方法停止
             kCFRunLoopRunTimedOut:runloop设置的时间已到
             kCFRunLoopRunHandledSource:当returnAfterSourceHandled值为ture时,一个source被执行完
 */
func CFRunLoopRunInMode(_ mode: CFRunLoopMode!, _ seconds: CFTimeInterval, _ returnAfterSourceHandled: Bool) -> CFRunLoopRunResult

/**
 * 唤醒runloop的方法,参数为需要唤醒的runloop
 * 当一个runloop正在等一个source准备或者timer 执行 fire 的时候runloop处于休眠状态。
 * 如果没有source或者timer准备好,runloop会保持休眠直到超时或者被唤醒。
 * 当runloop被修改,例如添加了一个source,你需要唤醒runloop将其加入队列
 */
func CFRunLoopWakeUp(_ rl: CFRunLoop!)

/**
 * 停止runloop
 * 通过CFRunLoopRun()或者CFRunLoopRunInMode(_:_:_:)再次运行runloop 
 * 仅当前runloop 及其子runloop会停止,不影响父runloop()
 */
func CFRunLoopStop(_ rl: CFRunLoop!)

/**
 * 判断其他runloop是否处于等待状态,如果用于判断当前runloop,则永远返回false
 */
func CFRunLoopIsWaiting(_ rl: CFRunLoop!) -> Bool
  • 管理 Sources 的方法
/**
 * 给runloop添加CFRunLoopSource对象
 * 如果添加的是source0, 当前方法会调用 schedule 回调方法为source指明上下文 
 * 一个CFRunLoopSource对象能同时被多个runloop添加而且可以制定多个不同的mode
 * 当source已发出信号,一旦被runloop查明就会执行source
 * 如果该runloop在指定mode已有该source,则CFRunLoopAddSource这个方法不会重复对source进行添加
 */
func CFRunLoopAddSource(_ rl: CFRunLoop!, _ source: CFRunLoopSource!, _ mode: CFRunLoopMode!)

/**
 *判断runloop在某个mode下是否有指定的CFRunLoopSource对象
 * 如果source被加入 commonModes,该方法一定返回true。不论mode参数是commonModes还是任意被加入commonModes的mode
 */
func CFRunLoopContainsSource(_ rl: CFRunLoop!, _ source: CFRunLoopSource!, _ mode: CFRunLoopMode!) -> Bool

/**
 * 从runloop中移除指定的CFRunLoopSource对象
 * 如果指定的source0,当前方法会调用cancel回调方法具体说明source的上下文
 * 如果在指定runloop的指定mode下不含有这个source,则该方法不做任何操作
 */
func CFRunLoopRemoveSource(_ rl: CFRunLoop!, _ source: CFRunLoopSource!, _ mode: CFRunLoopMode!)
  • 管理 Observers 的方法
/**
 * 给runloop添加CFRunLoopObserver对象
 * 一个CFRunLoopObserver对象只能同时被一个runloop添加,但是可以被添加到多个不同的mode
 * 如果该runloop在指定mode已有该observer,则CFRunLoopAddObserver这个方法不会重复对observer进行添加
 */
func CFRunLoopAddObserver(_ rl: CFRunLoop!, _ observer: CFRunLoopObserver!, _ mode: CFRunLoopMode!)

/**
 *判断runloop在某个mode下是否有指定的CFRunLoopObserver对象
 * 如果observer被加入 commonModes,该方法一定返回true。不论mode参数是commonModes还是任意被加入commonModes的mode
 */
func CFRunLoopContainsObserver(_ rl: CFRunLoop!, _ observer: CFRunLoopObserver!, _ mode: CFRunLoopMode!) -> Bool

/**
 * 如果在指定runloop的指定mode下不含有这个observer,则该方法不做任何操作
 */
func CFRunLoopRemoveObserver(_ rl: CFRunLoop!, _ observer: CFRunLoopObserver!, _ mode: CFRunLoopMode!)
  • 管理 Run Loop Modes 的方法
/**
 * 将指定mode加入commonModes
 * Sources、timers、observers都可以在多个mode中注册,只能在一个模式中运行。
 * commonModes是mode的一个集合,你可以定义 Sources、timers、observers的集合来被这些mode共用
 * 你只需在Commonmodes中注册一次source,source就会被自动在Commonmodes包含的模式中注册
 * 当一个mode被加入Commonmodes,在新mode加入之前已注册的Sources、timers、observers也会被自动加入新的mode
 * 一旦一个mode被加入Commonmodes,就不能被从中移除
 * 如果 sources、timers、observers的添加、包含、移除方法中的mode参数传入Commonmodes,会作用于Commonmodes包含的所有mode
 */
func CFRunLoopAddCommonMode(_ rl: CFRunLoop!, _ mode: CFRunLoopMode!)

//返回一个包含runloop中所有定义的mode的数组
func CFRunLoopCopyAllModes(_ rl: CFRunLoop!) -> CFArray!

/**
 * 返回runloop当前运行的mode
 * 如果runloop不是运行状态,返回NULL
 * 当runloop为当前线程的runloop时, 返回的mode代表当前代码运行环境的mode 
 */
func CFRunLoopCopyCurrentMode(_ rl: CFRunLoop!) -> CFRunLoopMode!
  • 管理Timers 的方法
/**
 * 向runloop的一个mode中加入timer
 * 一个 timer 只能同时被加入一个runloop ,可以被加入不同的mode
 * 如果runloop的mode中已含有timer,则该方法不做任何操作
 */
func CFRunLoopAddTimer(_ rl: CFRunLoop!, _ timer: CFRunLoopTimer!, _ mode: CFRunLoopMode!)

/**
 * 获得下一个timer的开始时间
 */
func CFRunLoopGetNextTimerFireDate(_ rl: CFRunLoop!, _ mode: CFRunLoopMode!) -> CFAbsoluteTime

/**
 * 从runloop的指定mode中移除timer
 * 如果runloop的mode不包含这个timer,该方法不做任何操作
 */
func CFRunLoopRemoveTimer(_ rl: CFRunLoop!, _ timer: CFRunLoopTimer!, _ mode: CFRunLoopMode!)

/**
 * 判断runloop的mode下是否包含指定的timer
 * 如果timer被加入commonModes,返回值始终为true。不论mode参数是commonModes还是任意被加入commonModes的mode
 */
func CFRunLoopContainsTimer(_ rl: CFRunLoop!, _ timer: CFRunLoopTimer!, _ mode: CFRunLoopMode!) -> Bool
  • 闭包调用
/**
 * 向runloop的特定mode下,加入一个可执行闭包
 * block: 将被执行的闭包,闭包在方法调用结束前会被拷贝
 * 当runloop在指定的mode中运行时,block就会被执行,你也可以在闭包中通过cocoa提供的方法转移到其他线程执行某些方法
 * 你能用它作为一些其他操作的备用方案,例如向其他线程的runloop加入timer或使用CFMessagePort在线程间通信
 * 该方法只会讲block加入队列不会去唤醒或运行runloop。下次runloop被唤醒时才回执行block。
 * 如果你想block立即执行,你需要调用CFRunLoopWakeUp(_:) 方法
 */
func CFRunLoopPerformBlock(_ rl: CFRunLoop!, _ mode: CFTypeRef!, _ block: (() -> Void)!)
  • 获得runloop的类型ID
/**
 * 返回runloop未公开的类型ID(唯一标识)
 */
func CFRunLoopGetTypeID() -> CFTypeID
  • 数据类型
//runloop的实例对象 oc中称为CFRunLoopRef
CFRunLoop
  • 常量
//runloop退出的原因(CFRunLoopRunInMode()方法的返回值)
public enum CFRunLoopRunResult : Int32 {
    case finished
    case stopped
    case timedOut
    case handledSource
}

//一个模拟的mode,管理加入其中的mode
static let commonModes: CFRunLoopMode!
//不指定runloop运行的模式,则默认运行于该模式
static let defaultMode: CFRunLoopMode!

推荐阅读更多精彩内容

  • 什么是Run Loops RunLoops是与线程相关联的基础部分,一个Run Loop就是事件处理循环,他是用来...
    傻傻小萝卜阅读 720评论 0 5
  • 先贴下 apple doc, 本文基本是对照 doc 的翻译:https://developer.apple.co...
    brownfeng阅读 6,421评论 8 111
  • Run Loops 下面会用一些陌生的或者容易让人混淆的字符,我们先来统一概念再继续,这样能够让你更加愉快的阅读:...
    董二千阅读 330评论 0 1
  • 简介 Run loops are part of the fundamental infrastructure a...
    frankisbaby阅读 83评论 0 0
  • 什么是Run Loops Run Loops是与线程想关联的基础部分。一个Run Loop就是事件处理循环,它是用...
    李白不读书阅读 482评论 3 7
  • 就算 全世界都与我为敌 我也要 坚持下去 因为 在我的梦里 没有无谓的过去 只有对更加美好的希冀 就算 全世界都把...
    文展阅读 242评论 14 3
  • 今天尝试了一下古诗来聚宝,选的是《春晓》,刚开始是每句一条,小助教不是很有信心,说不认识字,我说相信你可以拼好,于...
    蜂蜜辣椒汁阅读 45评论 0 0
  • 2016就要过去了,最后一天的晚上十点,我应酬完回到公司,复习了《经济学原理》,喝了两杯甘普,坐下来整理一下今年的...
    榆树阅读 164评论 0 0