iOS RunLoop 监控卡顿的理解

173 阅读1分钟

通过一段监控卡顿代码更深入理解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, 然后就会往下执行开始记录卡顿信息。