卡顿优化 FPS(CADisplayLink) FPS只要保持在50~60之间,用户就不会感到界面卡顿 YYFPSLabel CADisplayLink *_link; // 创建CADisplayLink并添加到主线程的RunLoop中 _link = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(tick:)]; [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 当把CADisplayLink对象add到runloop中后,selector就能被周期性调用,类似 于NSTimer被启动了;执行invalidate操作时, CADisplayLink对象就会从 runloop中移除,selector 调用也随即停止,类似于NSTimer的invalidate方法 CADisplayLink的selector 默认调用周期是每秒60次,这个周期可以通过 frameInterval属性设置 比如当 frameInterval设为2,每秒调用就变成30次 CADisplayLink在正常情况下会在每次刷新结束都被调用,但是一旦卡顿就会不 精确 同timer一样,依赖runloop都会存在不精确问题 RunLoop观察者检测卡顿 原理: source0 处理的是 app 内部事件,包括 UI 事件,每次处理的开始和结束的耗时 决定了当前页面刷新是否正常,即 kCFRunLoopBeforeSources 和 kCFRunLoopAfterWaiting 之间 创建一个子线程去监听主线程状态变化 通过dispatch_semaphore 在主线程进入上面两个状态时发送信号量 若超过时间后还未接收到主线程发出的信号量则可判断为卡顿 保存当前调用栈信息 子线程Ping 检测卡顿 原理: 根据卡顿发生时,主线程无响应的原理,创建一个子线程循环去Ping主线程, Ping之前先设卡顿置标志为True,再派发到主线程执行设置标志为False 最后子线程在设定的阀值时间内休眠结束后判断标志来判断主线程有无响应 卡顿 堆栈获取框架 卡顿最大等待时间要小于watchDog 对应时间: WatchDog 在不同状态下设置的不同时间,如下所示:启动(Launch):20s; 恢复(Resume):10s;挂起(Suspend):10s;退出(Quit):6s;后台 (Background):3min signal crash 收集的时候注册信号,可以收集崩溃时日志和堆栈信息。 但是卡顿却不适应 PLCrashReporter 微信开源 matrix-ios卡顿监 KSCrash 友盟 Bugly 这些框架最基本的功能就是**获取线程调用栈**,并获取调用栈函数符号信息, 比如函数名称、函数地址、函数所在的库等