《iOS面试之道》读书笔记 - NSRunLoop

Run Loop 基本概念

Run Loop就是一个在线程(thread)里不停执行的do-while循环。当线程接收到事件(event)时,Run Loop 内的事件处理会使用对应的句柄(handler)处理事件。

Run Loop 接受的事件可分为两种不同的源(source),Input source传递异步事件,通常是其他线程或应用发送过来的消息(message)。Timer sources传递同步事件,即发生于特定时间的或以一定时间间隔循环发送的事件。

image

上图展示了 Run Loop 的工作原理:Run Loop 运行与线程之中,从Input sourceTimer sources接受事件,然后调用相应的 handler 处理事件。iOS框架 Foundation 中定义了 Run Loop 的实现类NSRunLoop

Run Loop 与线程的关系

Run Loop 与线程是一一对应的关系。每一个线程都有且仅有一个 Run Loop 与其对应,没有线程,就没有 Run Loop。在iOS应用中,主线程的 Run Loop 是默认启动的,而其他线程的 Run Loop 默认是不启动的。苹果为我们提供了两种获取 Run Loop 对象的方式:

获取的 Run Loop 对象的线程安全性取决于你所使用的API。Core Foundation 中的函数通常是线程安全的,可以从任何线程调用。但是,如果你正在执行修改 Run Loop 配置的操作,那么最佳实践是尽可能在 Run Loop 所在的线程进行这些操作。

NSRunLoop类不具有线程安装性。如果你使用NSRunLoop类来修改 Run Loop,则应仅从持有该 Run Loop 的线程内执行操作。

Run Loop 的组成部分

一个 Run Loop 包含多个 Mode,每个 Mode 包含多个 Sources、Objservers 和 Timers。每次调用 Run Loop 时,需要指定一种 Mode,此时 Run Loop 只能处理该 Mode 包含的Sources、Objservers 和 Timers[1]

苹果官方文档中提到的 Mode 类型有五种:

iOS中可供调用的只有NSDefaultRunLoopModeNSRunLoopCommonModes两个,其中NSRunLoopCommonModes是一个集合,其中默认包括NSDefaultRunLoopModeNSEventTrackingRunLoopMode

何时使用 Run Loop?

苹果官方文档[2]指出,需要显式运行 Run Loop 的唯一时机是为应用程序创建辅助线程(secondary thread)时。例如,如果你需要执行以下任何操作,则需要启动 Run Loop:

  • 使用端口(mach port)或自定义输入源(custom input source)与其他线程通信。

  • 在线程中使用计时器(timers)。

  • 使用任何performSelector方法。

  • 保持线程以执行周期任务。

其中常用的是timers和performSelector

Timer

计时器源(timer source)在将来的预设时间将事件同步传递给线程。苹果为我们提供了两种计时器的实现,NSTimerCFRunLoopTimerRef

RunLoop为了节省资源,并不会在非常准确的时间点回调这个Timer。Timer 有个属性叫做 Tolerance (宽容度),标示了当时间点到后,容许有多少最大误差。如果某个时间点被错过了,例如执行了一个很长的任务,则那个时间点的回调也会跳过去,不会延后执行。就比如等公交,如果 10:10 时我忙着玩手机错过了那个点的公交,那我只能等 10:20 这一趟了。[2]

performSelector:

当调用NSObjectperformSelecter:afterDelay:后,实际上其内部会创建一个 Timer 并添加到当前线程的 RunLoop 中。所以如果当前线程没有 RunLoop,则这个方法会失效。当调用performSelector:onThread:时,实际上其会创建一个 Timer 加到对应的线程去,同样的,如果对应线程没有 Run Loop 该方法也会失效。[2]


  1. 深入理解RunLoop

  2. Threading Programming Guide - Run Loops

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容