美文网首页iOS IOS开发知识点
iOS开发中利用RunLoop监控卡顿

iOS开发中利用RunLoop监控卡顿

作者: 梁森的简书 | 来源:发表于2021-02-19 11:23 被阅读0次

    造成App卡顿的一些原因

    1. 图片过多、过大,绘制图片耗时大
    2. 在主线程上执行一些耗时操作,如:网络请求
    3. 在主线程上做大量的IO操作
    4. 死锁、主线程和子线程抢锁

    总而言之,只要主线程上任务耗时过长,无法及时响应用户操作或其他事件(或计时器)就是卡顿。

    三方工具

    https://github.com/Tencent/matrix

    监听卡顿原理

    既然是主线程上任务耗时过长导致的卡顿,那么我们就需要去监听主线程。而线程的消息事件是依赖于runLoop的,那么我们就需要去监听主线程对应的runLoop的状态。

    卡顿即线程受阻,runLoop处于什么状态我们就可以认定为线程受阻呢?
    1.runLoop进入睡眠前方法执行时间过长而导致无法进入睡眠
    2.runLoop被唤醒后接受消息时间过长而无法进入下一步
    所以kCFRunLoopBeforeSources和kCFRunLoopAfterWaiting这两个状态是需要监听的。
    实现:
    我们需要创建一个runLoop观察者,然后将此观察者添加到主线程对应的runLoop的common模式下,同时创建一个子线程用来定时监听主线程的runLoop状态。
    代码:

    //创建子线程监控
    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
    });
    

    当监听到卡顿后我们就将堆栈信息记录下来并进行上报。

    程序中认定卡顿的标准

    可以设置一个时间阀值,如果超过了这个阀值就认定为卡顿。

    相关文章

      网友评论

        本文标题:iOS开发中利用RunLoop监控卡顿

        本文链接:https://www.haomeiwen.com/subject/gvwniktx.html