SEO基础

SEO基础

Products

当前位置:首页 > SEO基础 >

面试中RunLoop究竟在循环什么内容?

96SEO 2026-05-07 17:47 1


这两天我又把 RunLoop 的相关文档和源码重新翻了一遍。这个话题在 iOS 开发圈子里其实一点dou不新,甚至Yi经算是老朋友了但有意思的是:hen多同学平时天天在和它打交道,却未必真的知道它在干什么。

面试中RunLoop究竟在循环什么内容?

说实话,现在的面试环境,大家dou懂,内卷得厉害。Ru果你去面初级岗位,这个问题基本上是跑不了的。想当年作者还是初级的时候,连 RunLoop 是什么dou不知道,每次遇到这种问题dou会菊花一紧,生怕回答的少了同时也怕回答的不够全面。hen多人第一次kan Mode,会觉得这名字有点抽象,甚至有点云里雾里。

别被“八股文”吓跑,RunLoop 其实hen朴素

我们先别急着上源码,也别急着背那些枯燥的概念。先记住一句话:RunLoop 和线程是一一对应理解的。

你Ke以把它想象成线程的管家。一个程序Neng一直运行,就是基于 runloop。每个线程Ru果想继续运行,不被释放,就必须有一个 runloop 来不停地跑圈,以来处理线程里面的各种事件和消息。主线程默认是开启一个 runloop 的,而子线程通常需要你自己去决定是否启动它。

从概念上讲,一个 RunLoop 主要围绕四类东西运转:Source、Timer、Observer以及 Mode。它的本质,和下面这段伪代码几乎一模一样:

function loop {
  while  {
    const event = getNextEvent;
    if  {
      handle;
    } else {
      sleep;
    }
  }
}

这就是 RunLoop 的核心逻辑:一个“事件循环”模型。线程进入循环后反复执行“接收消息 -> 处理消息 -> 没消息就休眠 -> 被唤醒后继续处理”这一套流程。Apple 官方文档也明确说明,RunLoop 是一个 event processing loop;而从经典的 CFRunLoop 源码解析视角来kan,它也完全Ke以理解成线程内部长期运行的事件循环。

这个设计非常重要。否则主线程Ru果一直死循环轮询事件,手机发热和掉电会快得像开了涡轮;Ru果线程处理完一个任务就退出,那 App 也根本不可Neng持续响应事件。宇宙不会允许这种离谱工程存在太久。

它到底解决了什么问题?

所以从结果上kan,RunLoop 解决的是两个核心问题:

线程保活: 让线程在没事干的时候睡觉,不占用 CPU,有事的时候立刻醒来干活。

事件调度: 把各种乱七八糟的事件统一管理,按顺序分发。

Mode:那个让 Timer 失效的“筛子”

这就像你开了一个筛子。默认状态下线程处理一部分事件;当用户开始拖拽 ScrollView 时RunLoop Ke以切到另一个 mode,只处理和拖拽geng相关的输入,暂时忽略别的一些东西。Apple 也明确说明了mode 的作用是根据 source 来过滤事件,而不是根据事件类型本身来过滤。

Apple 文档里把 RunLoop Mode 描述为:一组要监听的 input sources、timers,以及要通知的 observers 的集合。每次 RunLoop 运行时只会在某个特定 mode 下处理对应的事件;不属于当前 mode 的 source/timer,不会在这一轮被处理。

这句话翻译成人话就是:RunLoop 当前这一轮,只kan哪一组事件。

常见的几个模式Ke以先记住:

DefaultMode平时没事干就在这个模式。

UITrackingRunLoopMode拖拽 ScrollView 时切到这个模式。

UIInitializationRunLoopMode启动时用的,用完就换。

为什么滚动时 Timer 不动了?

这个问题几乎是 RunLoop 的必考题了。原因并不神秘:你创建出来的 Timer,大概率默认被加在了 DefaultMode 里;而当你拖拽 ScrollView 时主线程 RunLoop 会进入 tracking 相关的 mode,这时候默认 mode 下的 timer 就不会被处理。

Apple 文档明确说明,timer 和 source dou和特定 mode 绑定;不在当前 mode 里的对象,要等 RunLoop 以后切回支持它的 mode 才会触发。这也就合理的解释了为什么当我们拖动 textView 的时候 timer 方法不执行了这也是一种 NSTimer 不准的情况。

所以解决思路也就顺理成章了:把 Timer 加到 CommonModes。

NSTimer *timer = ;
 addTimer:timer forMode:NSRunLoopCommonModes];

这里的 common 本质上不是一个真正的独立 mode,而是一个“公共模式集合”。把 timer 加进去以后它就Neng在多种 common mode 下dou被监控,自然也就不会在滚动时轻易“哑火”了。

Source0 与 Source1:事件从哪来?

Ru果你平时kan的是 CFRunLoop 源码分析文章,那还会经常见到 Source0 和 Source1 这套说法。Ke以先粗暴理解成:

Apple 官方主要把 input source 分成两类:

Source0: 非基于 Port 的,也就是那些手动触发的事件,比如点击按钮、触摸屏幕。这种事件需要你主动调用 CFRunLoopSourceSignal 来唤醒 RunLoop。

Source1: 基于 Port 的,也就是通过内核发消息过来的,比如硬件中断、系统消息。这种是主动“唤醒” RunLoop 的。

触摸、手势、各种输入事件之所以Neng不断进入 App,被分发到 UIWindow、UIView、UIGestureRecognizer,背后同样离不开主线程 RunLoop 对事件源的处理。经典解析中也展示了系统事件如何通过 Source1 进入应用内部分发链路。

Observer:默默无闻的监工

Observer 不产生事件,它负责观察 RunLoop 当前走到了哪一步。Apple 文档列出的典型观察时机包括:Entry、BeforeTimers、BeforeSources、BeforeWaiting、AfterWaiting、Exit。

这个东西hen关键,因为系统里hen多“顺便Zuo一下”的工作,恰恰就是挂在这些观察点上的。

经典分析里提到,主线程 RunLoop 上挂了和 autorelease pool 相关的 observer:进入 loop 时创建池,准备休眠时销毁旧池并重建,退出 loop 时再Zuo一次销毁。也就是说我们hen多主线程回调,其实天然就被 autorelease pool 包着。AutoreleasePool 在 RunLoop 的两次 sleep 之间对 AutoreleasePool 进行 pop 和 push,将这次 loop 产生的临时对象清理掉。

此外hen多 setNeedsLayoutsetNeedsDisplay 并不会让 UI 立刻重绘,而是先标记“需要geng新”,再等到 RunLoop 的某个合适时机统一提交。经典分析中把这部分和 BeforeWaiting / Exit 这些阶段关联了起来。

线程保活:别让子线程“猝死”

hen多同学在子线程里写个 Timer,结果发现根本不回调,本质原因通常不是 Timer 坏了而是线程的 RunLoop 根本没跑,或者刚跑起来就退出了。

Apple 文档里给出的说法是:每个线程dou有关联的 RunLoop 对象,主线程的 RunLoop 会由应用框架自动配置并运行,而二级线程是否运行 RunLoop,则取决于你自己。只有在你真的需要它的时候,才需要显式启动。

还有一个hen容易踩坑的点:RunLoop 里必须至少有一个输入源或者 timer,否则一启动就会立刻退出。 Apple 官方文档对此写得hen直白。

一个hen常见的“子线程保活”写法大概是这样:

- threadMain {
    @autoreleasepool {
        NSRunLoop *runLoop = ;
        // 添加一个 Port,防止 RunLoop 因为没事干而直接退出
         forMode:NSDefaultRunLoopMode];
        // 启动 RunLoop
        ;
    }
}

这个写法的核心不是 NSMachPort 本身有多神秘,而是:先往 RunLoop 里塞一个 source,避免它因为空空如也而直接退出,然后再让 RunLoop 跑起来。 Apple 官方文档也明确说明,secondary thread 的 RunLoop 在启动前必须至少附着一个 input source 或 timer,否则会立刻结束。

Apple 给出的建议其实hen实用:只有当子线程需要geng强交互性时才需要显式运行 RunLoop。 比如下面这些场景:

需要使用端口或其他自定义输入源来与其他线程通信。

需要在线程上执行定时器任务。

需要使用 performSelector... 系列方法。

Apple 官方文档明确说了:performSelector:onThread: 这一类调用,目标线程必须有一个 active run loop;performSelector:withObject:afterDelay: 也是在当前线程的下一次 run loop cycle 中调度执行。

它是一把钥匙,不是装饰品

所以理解 RunLoop,不只是为了背面试题,而是为了在遇到卡顿、定时器异常、线程保活、异步回调这些问题时不至于两眼一黑,开始对着代码Zuo法事。

我一直觉得,RunLoop 这个东西Zui容易被误解的地方,在于它听起来太“底层”了于是hen多人会下意识觉得:业务开发也用不上。但真相往往比较朴素,甚至有点滑稽:你不是用不上 RunLoop,而是你天天在被 RunLoop 影响。

hen多平时kan起来零碎的问题,比如 Timer 在滚动时失效、子线程任务不回调、performSelector 不执行、UI 为什么不是立刻刷新,本质上douNeng用 RunLoop 这套模型解释清楚。这些问题kan起来东一榔头西一棒子,实际上背后douNeng收敛到同一个东西:RunLoop。

Ru果你的线程只是Zuo一个明确的、一次性的耗时任务,比如图片解码、文件处理、纯计算,那干完退出往往geng合适,没必要强行塞一个 RunLoop 进去。别什么dou开火车,线程也会累。

所以 RunLoop 这东西,真的不是为了面试八股才学。它geng像是一把钥匙:平时你可Neng把它丢在抽屉里但一旦遇到线程、事件、时序、刷新相关的问题,它就会突然变得非常好用。

Apple 文档里把一次 RunLoop 的执行顺序列得hen清楚,大体Ke以压缩成下面这条主线:先通知 observer -> 处理 timer/source -> 没事就休眠 -> 被 timer、source、超时或显式唤醒后再继续处理。

这也是为什么你不Neng把 NSTimer 当成一把精确到毫秒的手术刀。它geng像一个“尽量按时提醒你”的闹钟,而不是原子钟。毕竟Ru果当前 RunLoop 正在处理一个耗时hen长的 block,那 Timer 也只Neng排队等着。

Zui后Ru果你kan过一些调用栈或者源码解析文章,会发现 RunLoop 的底层核心休眠/唤醒机制和 mach port 消息密切相关;这也是为什么它NengZuo到“没事就睡,有事马上醒”。这也不对。Apple 文档提到,Core Foundation 那套 API 通常是线程安全的;但 NSRunLoop 本身并不像底层 CFRunLoopRef 那么天然线程安全,Zui好只在拥有它的线程里修改它。

希望大家下次再面对这个问题时Neng自信地告诉面试官:RunLoop 循环的不仅仅是代码,geng是整个 App 的生命线。


标签: RunLoop

SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback