iOS开发高手课
戴铭
前滴滴出行技术专家
立即订阅
11466 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 锚定一个点,然后在这个点上深耕
免费
基础篇 (20讲)
01 | 建立你自己的iOS开发知识体系
02 | App 启动速度怎么做优化与监控?
03 | Auto Layout 是怎么进行自动布局的,性能如何?
04 | 项目大了人员多了,架构怎么设计更合理?
05 | 链接器:符号是怎么绑定到地址上的?
06 | App 如何通过注入动态库的方式实现极速编译调试?
07 | Clang、Infer 和 OCLint ,我们应该使用谁来做静态分析?
08 | 如何利用 Clang 为 App 提质?
09 | 无侵入的埋点方案如何实现?
10 | 包大小:如何从资源和代码层面实现全方位瘦身?
11 | 热点问题答疑(一):基础模块问题答疑
12 | iOS 崩溃千奇百怪,如何全面监控?
13 | 如何利用 RunLoop 原理去监控卡顿?
14 | 临近 OOM,如何获取详细内存分配信息,分析内存问题?
15 | 日志监控:怎样获取 App 中的全量日志?
16 | 性能监控:衡量 App 质量的那把尺
17 | 远超你想象的多线程的那些坑
18 | 怎么减少 App 电量消耗?
19 | 热点问题答疑(二):基础模块问题答疑
20 | iOS开发的最佳学习路径是什么?
应用开发篇 (12讲)
21 | 除了 Cocoa,iOS还可以用哪些 GUI 框架开发?
22 | 细说 iOS 响应式框架变迁,哪些思想可以为我所用?
23 | 如何构造酷炫的物理效果和过场动画效果?
24 | A/B 测试:验证决策效果的利器
25 | 怎样构建底层的发布和订阅事件总线?
26 | 如何提高 JSON 解析的性能?
27 | 如何用 Flexbox 思路开发?跟自动布局比,Flexbox 好在哪?
28 | 怎么应对各种富文本表现需求?
29 | 如何在 iOS 中进行面向测试驱动开发和面向行为驱动开发?
30 | 如何制定一套适合自己团队的 iOS 编码规范?
31 | iOS 开发学习资料和书单推荐
32 | 热点问题答疑(三)
原理篇 (6讲)
33 | iOS 系统内核 XNU:App 如何加载?
34 | iOS 黑魔法 Runtime Method Swizzling 背后的原理
35 | libffi:动态调用和定义 C 函数
36 | iOS 是怎么管理内存的?
37 | 如何编写 Clang 插件?
38 | 热点问题答疑(四)
原生与前端共舞 (5讲)
39 | 打通前端与原生的桥梁:JavaScriptCore 能干哪些事情?
40 | React Native、Flutter 等,这些跨端方案怎么选?
41 | 原生布局转到前端布局,开发思路有哪些转变?
42 | iOS原生、大前端和Flutter分别是怎么渲染的?
43 | 剖析使 App 具有动态化和热更新能力的方案
用户故事 (1讲)
用户故事 | 我是如何学习这个专栏的?
结束语 (1讲)
结束语 | 慢几步,深几度
iOS开发高手课
登录|注册

13 | 如何利用 RunLoop 原理去监控卡顿?

戴铭 2019-04-09
你好,我是戴铭。今天,我来和你说说如何监控卡顿。
卡顿问题,就是在主线程上无法响应用户交互的问题。如果一个 App 时不时地就给你卡一下,有时还长时间无响应,这时你还愿意继续用它吗?所以说,卡顿问题对 App 的伤害是巨大的,也是我们必须要重点解决的一个问题。
现在,我们先来看一下导致卡顿问题的几种原因:
复杂 UI 、图文混排的绘制量过大;
在主线程上做网络同步请求;
在主线程做大量的 IO 操作;
运算量过大,CPU 持续高占用;
死锁和主子线程抢锁。
那么,我们如何监控到什么时候会出现卡顿呢?是要监视 FPS 吗?
以前,我特别喜欢一本叫作《24 格》的杂志,它主要介绍的是动画片制作的相关内容。那么,它为啥叫 24 格呢?这是因为,动画片中 1 秒钟会用到 24 张图片,这样肉眼看起来就是流畅的。
FPS 是一秒显示的帧数,也就是一秒内画面变化数量。如果按照动画片来说,动画片的 FPS 就是 24,是达不到 60 满帧的。也就是说,对于动画片来说,24 帧时虽然没有 60 帧时流畅,但也已经是连贯的了,所以并不能说 24 帧时就算是卡住了。
由此可见,简单地通过监视 FPS 是很难确定是否会出现卡顿问题了,所以我就果断弃了通过监视 FPS 来监控卡顿的方案。
那么,我们到底应该使用什么方案来监控卡顿呢?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《iOS开发高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(42)

  • Geek_a03ab1
    为什么监控 kCFRunLoopBeforeSources、kCFRunLoopAfterWaiting这两个事件就能判断出卡顿呢?为什么不是kCFRunLoopBeforeWaiting、kCFRunLoopAfterWaiting这两个事件呢?没想明白,老师能展开说下吗?
    2019-04-09
    3
    25
  • WeZZard
    單純監控 FPS 確實不行,因為很多卡頓其實是 FPS 變化率的大幅變化(既 FPS 一階導數的波動)所造成的。

    比如說點 A 花一秒匀速位移至點 B,秒間平均幀率 60FPS,但是前 59/60 秒才跑了一幀出來,剩下 59 幀都在後 1/60 秒跑出來,那麼用戶必然看到的是點 A 花了 59/60 秒停在 A + ((B - A)/60) 這個位置上,然後突然「飛」到了 B 點上。

    所以監控 FPS > 24 的同時還要監控 FPS 變化率的波動。而這個波動的成因其實就是主線程上計算任務的性能衝擊。
    2019-04-10
    12
  • Keep-Moving
    PLCrashReporter怎么和卡顿检测结合起来呢?我理解它是收集崩溃信息的,但卡顿又不是一定会崩溃

    作者回复: 卡顿后收集造成卡顿的原因

    2019-04-09
    11
  • 鼠辈
    这个3秒是不是太长了,1秒60帧,每帧16.67ms。runlooo会在每次sleep之前去刷新ui,这样的话如果掉了30帧,就是500ms左右,用户的体验就已经下去了,能感觉到卡顿了.
    2019-04-09
    7
  • Geek
    卡顿的原因讲的可以,但是讲的RunLoop让我听的头大,有几个疑问请教老师,
    1,线程与run loop是什么关系。
    2,mach_port是什么,第一次进入runloop,也是mach_port触发的吗,
    3.进入休眠状态的runloop为什么要等mach_port.
    4,系统会有多个runloop吗,不同runloop之间是串行还是并行执行的?
    2019-04-11
    2
    4
  • 金阳
    https://blog.ibireme.com/2015/05/18/runloop/ 这篇文章讲的更清晰些
    2019-07-31
    3
  • 董仕卿
    你这不是在讲runloop的源码嘛
    2019-05-05
    3
  • 戒惜舍得
    大神 可否来一篇TDD oc 和swift 希望都有
    2019-04-09
    2
  • 天涯
    runloop监听kCFRunLoopBeforeSources做ui刷新,为什么还需要监听kCFRunLoopAfterWaiting来判定卡顿
    2019-04-24
    1
    1
  • Geek__b82782469097
    请问swift是如何检测卡顿的呢?也是runloop么?
    2019-04-22
    1
  • Wechat Team
    文章提到可以『直接调用系统函数』来获取堆栈,但是通过注册那几个信号的方式获取堆栈,一般不是在闪退的情况下才可以触发回调吗?
    请老师指点

    作者回复: 获取堆栈的方法任何时候都可以调的。闪退只是一个时机

    2019-04-10
    1
  • 庞佳星
    老大,啥时候讲讲,resct native 和iOS的关系。谢谢啦,

    作者回复: 后面会专门说

    2019-04-10
    1
  • 鹏哥
    老师,请问下,如果我在用户滑动界面的时候不去加载图片,等停止滑动的时候再去加载图片,这个场景用runloop或者scrollview的代理来实现,和使用sdwebimage异步下载图片有什么区别,这几种方式貌似都没有影响用户滑动体验!

    作者回复: 图片少感觉不出,当图片大、列表长、快速滚动时会有区别

    2019-04-09
    1
  • hw20101101
    请问 DecoupleDemo 允许之后,以下句话是在哪里打印的?

    [UIWorkIntervalTiming] workIntervalStart: startTimestamp > targetTimestamp; rolling forward by 0.250000

    而且 DecoupleDemo 中并没有打印 卡顿的方法堆栈信息啊
    2019-12-04
  • Donovan Mitchell Sr.
    老师请问方法调用死循环可以用这个原理来监控吗?试了一下一旦子线程是有间隔地去监控的话就会被死循环给打断
    2019-11-26
  • 吃土豆的Panda 🍀
    怎么区分是ui操作,还是io操作,还是计算呢?如果不区分是不是信息数据很难维护,很难排查问题?
    2019-11-11
  • Master
    开启子线程监控那段代码看不懂:
    1、为什么只有 wait 没有 signal 这样的结果不就是 wait 返回结果一直不为 0;
    2、为什么是 while 死循环,每次监听回调都有一个死循环,n 次监听回调过来是否同时有 n 个死循环在检测;
    3、activity 为什么非得是那两个( kCFRunLoopBeforeSources、kCFRunLoopAfterWaiting);
    3、
    2019-11-04
  • 矮个子先生😝
    老师,看git上的代码,在监控回调里,有个if (++timeoutCount < 3)这个被注掉了,我想本来是需要的吧,但我改成 if (++timeoutCount < 2) ,两次监听都维持同一个状态,说明卡顿
    2019-10-29
  • 茄菲
    "将那些繁重而不紧急会大量占用 CPU 的任务(比如图片加载)放到空闲的 RunLoop 模式里执行就可以避开在 UITrackingRunLoopMode这个 RunLoop 模式时是执行"
    这样和将任务放置在异步线程里执行有什么区别呢?或者是这样有什么好处吗

    作者回复: 这样可以避免影响用户操作的流畅

    2019-08-15
    1
  • 茄菲
    如何检查卡顿
    CFRunLoopObserverContext context = {0,(__bridge void*)self,NULL,NULL};
    CFRunLoopObserverContext 创建少了一个参数
    2019-08-14
收起评论
42
返回
顶部