通过一段监控卡顿代码更深入理解RunLoop的运行机制,在Runloop的七种状态里, 在RunLoop运行中,kCFRunLoopAfterWaiting到kCFRunLoopBeforeSources这个之间的运行的总时间,是否会卡顿超时。
//创建子线程监控
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程开启一个持续的 loop 用来进行监控
while (YES) {
long semaphoreWait = dispatch_semaphore_wait(dispatchSemaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC));
if (semaphoreWait != 0) {
if (!runLoopObserver) {
timeoutCount = 0;
dispatchSemaphore = 0;
runLoopActivity = 0;
return;
}
//BeforeSources 和 AfterWaiting 这两个状态能够检测到是否卡顿
if (runLoopActivity == kCFRunLoopBeforeSources || runLoopActivity == kCFRunLoopAfterWaiting) {
//将堆栈信息上报服务器的代码放到这里
} //end activity
}// end semaphore wait
timeoutCount = 0;
}// end while
});
通过一个GCD的信号量机制,来检测卡顿,设置信号量超时3秒,如果在runloop执行中,如果超时dispatch_semaphore_wait会返回非0,
然后就会往下执行开始记录卡顿信息。