iOS runloop 學習筆記(三) - 彥祖葉孤城視頻總結

彥祖談runloop百度云地址:
鏈接: http://pan.baidu.com/s/1bpa9Lz5 密碼: qgrc

彥祖視頻中主要講內容不是和前兩篇文章一樣的理論內容,主要是圍繞如何在實際工作用用到 runloop,并且給了幾個使用實例.

NSTimer 在 tracking mode 的應用

這個應用在前面筆記中都有提到,這里就不展開.

通過runloop解決在 tableView 滾動時候停止加載圖片的需求

利用RunLoop 不同 mode 的特性,可以將圖片的加載放到NSDefaultRunLoopMode的mode里,這樣在滾動UITrackingRunLoopMode這個mode時不會被加載而影響到。

UIImage *downloadedImage = ...;
[self.avatarImageView performSelector:@selector(setImage:) withObject:downloadedImage afterDelay:0 inModes:@[NSDefaultRunLoopMode]];

runloop 解決在 tableView 中同時加載多個大圖的使用

runloop 中最先響應的 UI 的繪制, tableView 在滑動時就需要在一次 runloop 循環中繪制所有的屏幕上的圖片,如果在 cellForxxx 方法中有imageView.image = image 等代碼,這部分會非常消耗資源(尤其在圖片較大的情況),一次 runloop 執行時間太長, 就會導致 UI 響應變慢, 直觀感受就是 app 卡頓嚴重.

解決思路

原來是一次runloop 中繪制所有的 view 中顯示出來的圖片,那么為什么不在一次 runloop 時候只繪制一張圖片. 這樣每次 runloop 需要完成的內容較少,UI 才不會卡頓.

具體實踐

首先封裝一個task queue,用它觀察 RunLoop 的狀態, 當 RunLoop 的狀態是 kCFRunLoopBeforeWaiting,取出 queue 中的第一個 task 然后執行,然后將該 task 移除 queue. queue 中的 task 是一個個將耗時任務封裝的成的代碼塊. 在 tableView 的 cellForRowAtIndexPath 方法中,我們將 task 代碼塊加入到 queue 中,讓 queue 根據 RunLoop 的狀態每次在進入睡眠前執行一個 task.

具體的代碼 Demo:
https://github.com/diwu/RunLoopWorkDistribution

當前有更好的圖片相關性能優化的方法,這里只是提供了一種使用 RunLoop 進行優化的思路

runloop 監控 App 卡頓,并查找具體卡頓函數的方法

app 卡頓的定義

mainRunLoop 中一次 RunLoop 循環執行時間過長,導致新的事件傳遞到 RunLoop 中響應不及時, 直觀感受就是卡頓.因此可以通過一定方法求出,第一次進入 RunLoop 與第二次進入 RunLoop 之間的時間, 如果這個時間超過某閥值,就說明 App 卡頓.

具體實踐

使用 global 線程中監聽 mainRunLoop 的狀態, 使用使用 semaphore 來進行超時統計(超時時間就是 runloop 的閥值)管理. 如果連續多次超時,就使用 CrashReport 打印出當前函數調用棧的內容.

具體的代碼 Demo:
https://github.com/suifengqjn/PerformanceMonitor

Demo 地址中也對源碼有相應的解釋

ps 最后還有一篇非常好的文章:
yy 大神的筆記: http://blog.ibireme.com/2015/05/18/runloop/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容