簡單監測iOS卡頓的demo

發表於2016-06-20

前言

本文的demo程式碼也會更新到github上。

做這個demo思路來源於微信team的:微信iOS卡頓監控系統
主要思路:通過監測Runloop的kCFRunLoopAfterWaiting,用一個子執行緒去檢查,一次迴圈是否時間太長。
其中主要涉及到了runloop的原理。關於整個原理:深入理解RunLoop講解的比較仔細。
以下就是runloop大概的執行方式:

其中UI主要集中在__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(source0);
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(source1);之前。
獲取kCFRunLoopBeforeSourceskCFRunLoopBeforeWaiting再到kCFRunLoopAfterWaiting的狀態就可以知道是否有卡頓的情況。

NSTimer的實現

具體程式碼如下:

主要內容是首先在主執行緒註冊了runloop observer的回撥myRunLoopObserver
每次小迴圈都會記錄一下kCFRunLoopAfterWaiting的時間_waitStartTime,並且在kCFRunLoopBeforeWaiting制空。

另外開了一個子執行緒並開啟他的runloop(模仿了AFNetworking的方式),並加上一個timer每隔1秒去進行監測。

如果當前時長與_waitStartTime差距大於2秒,則認為有卡頓情況,並記錄了當前堆疊資訊。

PS:整個demo寫的比較簡單,最後獲取堆疊也僅獲取了當前執行緒的堆疊資訊([NSThread callStackSymbols]有同樣效果),也在尋找獲取所有執行緒堆疊的方法,歡迎指點一下。


更新:

瞭解到 plcrashreporter (github地址) 可以做到獲取所有執行緒堆疊。


更新2:

這篇文章也介紹了監測卡頓的方法:檢測iOS的APP效能的一些方法
通過Dispatch Semaphore保證同步這裡記錄一下。

寫一個Semaphore版本的程式碼,也放在github上:

用Dispatch Semaphore簡化了程式碼複雜度,更加簡潔。

參考資料

1.微信iOS卡頓監控系統
2. iphone——使用run loop物件
3.深入理解RunLoop
4.檢測iOS的APP效能的一些方法
5.iOS實時卡頓監控

相關文章