卡顿的原因
- CPU相关
- 在主线程做大量的 IO 操作;
- 在主线程上做网络同步请求;
- 过多线程资源抢夺;
- GPU相关
- 复杂 UI 、图文混排的绘制量过大;
- 大量的渲染算法
卡顿检测原理
- 通过监控 RunLoop 的状态来判断是否会出现卡顿。
RunLoop 的目的是,当有事件要去处理时保持线程忙,当没有事件要处理时让线程进入休眠。
如果 RunLoop 的线程,进入睡眠前方法的执行时间过长而导致无法进入睡眠,或者线程唤醒后接收消息时间过长而无法进入下一步的话,就可以认为是线程受阻了。如果这个线程是主线程的话,表现出来的就是出现了卡顿。
Runloop的六个状态
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry ,
kCFRunLoopBeforeTimers ,
kCFRunLoopBeforeSources ,
kCFRunLoopBeforeWaiting ,
kCFRunLoopAfterWaiting ),
kCFRunLoopExit ,
kCFRunLoopAllActivities
}
第一步
监听主线程runloop的状态变化
CFRunLoopObserverContext context = {0,(__bridge void*)self,NULL,NULL};
_runLoopObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &runloopObserverCallBack, &context);
CFRunLoopAddObserver(CFRunLoopGetMain(), _runLoopObserver, kCFRunLoopDefaultMode);
创建一个持续的子线程专门用来监控主线程的 RunLoop 状态。




