Swift工程添加卡顿监测

Swift工程添加卡顿监测


POCT项目在现阶段,越来越注意App性能方面的内容,前段时间大佬拿了一台新鲜出炉的iPhoneX,主要拿来做适配。大佬偶然发现日历页面的滑动返回,感觉会有卡顿情况,于是让不用跟进项目进度的我,看看什么原因,给出解决方案。

拿到手之后,先用Instrument查看了一下返回阶段相对耗时的event,大概定位到了位置。接下来的事情应该是查看对应方法,找到可以修改的内容,写个文档说明,交公。想法是美好的,但是实际上神经大条的我,诚惶诚恐的拿到iPhoneX之后,慢慢的来回滑动返回页,并没有很明显的感知到卡顿现象。WTF!!大佬既然说卡,那卡必然是存在的,但每个人对卡顿的感觉不一致。数据化卡顿时间,可以作为支持卡顿支撑点。

秉承想要将卡顿现象数据化的想法,对POCT的工程进行卡顿监测,也不用大佬们,拿着手机追在我屁股后面跟我说这里卡了,好好看看,好好改改,时时刻刻处于担惊受怕的状态中。通过实现POCT的卡顿监测,可以真实的反应POCT项目出现卡顿的所有情况,有计划的一一处理卡顿情况。让有问题的code无处遁形~

卡顿造成的原因

本文主要讲的是添加卡顿监测,但是在编写监测卡顿工具时,需要知道在“某个时间间隔”内停留在“某个方法”中即算造成了卡顿。在下面的介绍中,将会对“某个时间间隔”进行简单的说明,对之后的具体的时间间隔引入提供实际依据。

iOS图形呈现的原理如下图所示:

Vsync:信号,信号到达后如果缓冲区内有内容,就显示;如果缓冲区内没内容就会出现掉帧。

CADisplayLink:系统图形服务会通过通过 CADisplayLink机制通知App。

CPU:视图创建、布局计算、图片解码、文本绘制等。

GPU:变换、合成、渲染完成后将内容提交到缓冲区。

按照上述的概念,VSync信号的到达频率即上述所说的“某个时间间隔”,如果CPU+GPU的处理时间超过时间间隔即会有掉帧即卡顿情况。iOS中Vsync的刷新频率是0.01666秒,在设计卡顿检测工具中,会将该时间间隔作为单个任务处理的时间上限,超过此时间上限即视为卡顿。

关于时间间隔的说明如果有错误之处,可以进行说明。

以RunLoop作为切入点

主线程和Runloop是一一对应关系,Runloop控制着主线程的运作。反过来,如果主线程因为出现大量计算或者布局而导致卡顿的发生,Runloop肯定能够感知。以Runloop各个阶段运行的时间间隔,作为监测线程卡顿的依据这个想法貌似是可行的。下面将以上述想法作为切入点,对线程进行实时监测,逐一找到POCT中造成卡顿的操作。

通过阅读RunLoop的源码CFRunLoopRun方法可以知道UI的刷新主要是

kCFRunLoopBeforeSources-> kCFRunLoopBeforeWaiting

kCRunLoopAfterWaiting之后 所以如果在这两个阶段耗时超过0.0166秒的话,就可以判定主线程有卡顿情况。

通过信号量来保证来确保获取到主线程的状态。

下面代码是将时间间隔设置为0.03334秒(30帧)来obsever主线程,突出明显的卡顿现象。

因为一般viewWillAppear到viewDidAppear需要0.04秒,如果启动阶段会出现1次以上的提示,表示该页面的启动是存在卡顿的。

funcsetRunloopObserver(){

    letrunloop =CFRunLoopGetCurrent()

    letunmanaged =Unmanaged.passRetained(self)

    letuptr = unmanaged.toOpaque()

    letvptr =UnsafeMutableRawPointer(uptr)

    varcontent =CFRunLoopObserverContext(version:0, info: vptr, retain:nil, release:nil, copyDescription:nil)       

    enterObserver =CFRunLoopObserverCreate(kCFAllocatorDefault,CFRunLoopActivity.allActivities.rawValue,true,0, callBackObserve(), &content)CFRunLoopAddObserver(runloop, enterObserver,CFRunLoopMode.commonModes)               

    sema =DispatchSemaphore(value:0)letqueue =DispatchQueue.global()       

    queue.async {

        //循环while(true) {

            //等待时间0.033334秒,超过时间也继续执行

            let st =self.sema?.wait(timeout:DispatchTime.now() +0.033334)

            //如果超时执行st == .timeOut,非超时执行.success

            if st == .timedOut {

                ifself.activityEnum == .afterWaiting ||self.activityEnum == .beforeSources {

                //此部分功能需要丰富

                        print("-------------\(UIViewController.topMostViewController()) -------------")                                        

                        }               

                }           

        }       

    }           

}


privatefunccallBackObserve()->CFRunLoopObserverCallBack{

    return{ (observer, activity, context)in

        letwfSelf =Unmanaged.fromOpaque(context!).takeUnretainedValue()

        //获取到当前的activitywfSelf.activityEnum = activity

        //完成了一次观察,添加信号量初始化信号量为0

        wfSelf.sema?.signal()       

        }   

}

在不使用的时候将observer移除,减少不必要的内容消耗。

funcremoveRunloopObserver(){

        ifenterObserver ==nil{

        return

        }               

        CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), enterObserver, CFRunLoopMode.commonModes)   

}

在AppDelegate中调用setRunloopObserver方法,即可实现对POCT工程的卡顿监测。

CatonMonitoring.sharedInstance.setRunloopObserver()

获取POCT项目的卡顿点

关于日历页面返回手势卡顿的情况之前在别的机型上测试并没有明显的感觉。本以为可能是卡顿的情况相对小,但实际上通过卡顿监测还是能发现。然后在实际的测试过程中,用iPhone6对日历页面的返回手势进行反复操作,监测工具并没有出现提示。WTF?高贵的iPhoneX得到什么病?这周工作内容:无!😢.

虽然返回手势操作没有监测到卡顿情况,但是在POCT项目运行的过程中还是发现了以下几个问题:

HomePageController(首页)卡片控件中点击建议详情会出现卡顿情况。

RecordController(日历页) 点击“来姨妈了”SwitchButton,显示红色周期,会有卡顿情况。点击“爱爱”SwitchButton,对应的显示不会出现卡顿情况。

MinePhysiologicalInfoController(生理资料页),点击“月经是否规律”SwitchButton,显示后面的两个Cell会出现卡顿。

ExamineRecordController(检测记录页)右滑刷新操作,会造成卡顿。

弹出框的显示会出现卡顿。

之后会对其中出现的问题一一排查。如有必要,会在之后的文档中详细说明。

总结

关于卡顿监测工具在性能上对POCT的影响还需要进一步做测试,而且也没有对卡顿造成的具体位置进行定位。在后期会对某些第三方库进行调研,使工具能够确保将卡顿的原因成功上报。


如果文章内容有问题的地方,欢迎提问。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容