彥祖談runloop百度云地址:
鏈接: http://pan.baidu.com/s/1bpa9Lz5 密碼: qgrc
彥祖視頻中主要講內(nèi)容不是和前兩篇文章一樣的理論內(nèi)容,主要是圍繞如何在實(shí)際工作用用到 runloop,并且給了幾個(gè)使用實(shí)例.
NSTimer 在 tracking mode 的應(yīng)用
這個(gè)應(yīng)用在前面筆記中都有提到,這里就不展開(kāi).
通過(guò)runloop解決在 tableView 滾動(dòng)時(shí)候停止加載圖片的需求
利用RunLoop 不同 mode 的特性杏瞻,可以將圖片的加載放到NSDefaultRunLoopMode的mode里羊异,這樣在滾動(dòng)UITrackingRunLoopMode這個(gè)mode時(shí)不會(huì)被加載而影響到佣耐。
UIImage *downloadedImage = ...;
[self.avatarImageView performSelector:@selector(setImage:) withObject:downloadedImage afterDelay:0 inModes:@[NSDefaultRunLoopMode]];
runloop 解決在 tableView 中同時(shí)加載多個(gè)大圖的使用
runloop 中最先響應(yīng)的 UI 的繪制, tableView 在滑動(dòng)時(shí)就需要在一次 runloop 循環(huán)中繪制所有的屏幕上的圖片,如果在 cellForxxx 方法中有imageView.image = image 等代碼,這部分會(huì)非常消耗資源(尤其在圖片較大的情況),一次 runloop 執(zhí)行時(shí)間太長(zhǎng), 就會(huì)導(dǎo)致 UI 響應(yīng)變慢, 直觀感受就是 app 卡頓嚴(yán)重.
解決思路
原來(lái)是一次runloop 中繪制所有的 view 中顯示出來(lái)的圖片,那么為什么不在一次 runloop 時(shí)候只繪制一張圖片. 這樣每次 runloop 需要完成的內(nèi)容較少,UI 才不會(huì)卡頓.
具體實(shí)踐
首先封裝一個(gè)task queue,用它觀察 RunLoop 的狀態(tài), 當(dāng) RunLoop 的狀態(tài)是 kCFRunLoopBeforeWaiting,取出 queue 中的第一個(gè) task 然后執(zhí)行,然后將該 task 移除 queue. queue 中的 task 是一個(gè)個(gè)將耗時(shí)任務(wù)封裝的成的代碼塊. 在 tableView 的 cellForRowAtIndexPath 方法中,我們將 task 代碼塊加入到 queue 中,讓 queue 根據(jù) RunLoop 的狀態(tài)每次在進(jìn)入睡眠前執(zhí)行一個(gè) task.
具體的代碼 Demo:
https://github.com/diwu/RunLoopWorkDistribution
當(dāng)前有更好的圖片相關(guān)性能優(yōu)化的方法,這里只是提供了一種使用 RunLoop 進(jìn)行優(yōu)化的思路
runloop 監(jiān)控 App 卡頓,并查找具體卡頓函數(shù)的方法
app 卡頓的定義
mainRunLoop 中一次 RunLoop 循環(huán)執(zhí)行時(shí)間過(guò)長(zhǎng),導(dǎo)致新的事件傳遞到 RunLoop 中響應(yīng)不及時(shí), 直觀感受就是卡頓.因此可以通過(guò)一定方法求出,第一次進(jìn)入 RunLoop 與第二次進(jìn)入 RunLoop 之間的時(shí)間, 如果這個(gè)時(shí)間超過(guò)某閥值,就說(shuō)明 App 卡頓.
具體實(shí)踐
使用 global 線程中監(jiān)聽(tīng) mainRunLoop 的狀態(tài), 使用使用 semaphore 來(lái)進(jìn)行超時(shí)統(tǒng)計(jì)(超時(shí)時(shí)間就是 runloop 的閥值)管理. 如果連續(xù)多次超時(shí),就使用 CrashReport 打印出當(dāng)前函數(shù)調(diào)用棧的內(nèi)容.
具體的代碼 Demo:
https://github.com/suifengqjn/PerformanceMonitor
Demo 地址中也對(duì)源碼有相應(yīng)的解釋
ps 最后還有一篇非常好的文章:
yy 大神的筆記: http://blog.ibireme.com/2015/05/18/runloop/