1. 程式人生 > >iOS 卡頓總結優化

iOS 卡頓總結優化

1.除了UI部分,所有的載入操作都在後臺完成。

1.1  文字計算

如果一個介面中包含大量文字,文字的寬高計算會佔用很大一部分資源,並且不可避免。如果你對文字顯示沒有特殊要求,可以參考下 UILabel 內部的實現方式:用 [NSAttributedStringboundingRectWithSize:options:context:] 來計算文字寬高,

-[NSAttributedStringdrawWithRect:options:context:] 來繪製文字。儘管這兩個方法效能不錯,但仍舊需要放到後臺執行緒進行以避免阻塞主執行緒。

如果你用 CoreText 繪製文字,那就可以先生成

CoreText 排版物件,然後自己計算了,並且 CoreText 物件還能保留以供稍後繪製使用。

1.2文字渲染

螢幕上能看到的所有文字內容控制元件,包括 UIWebView,在底層都是通過 CoreText 排版、繪製為 Bitmap 顯示的。常見的文字控制元件 (UILabelUITextView 等),其排版和繪製都是在主執行緒進行的,當顯示大量文字時,CPU 的壓力會非常大。對此解決方案只有一個,那就是自定義文字控制元件,用 TextKit 或最底層的 CoreText 對文字非同步繪製。

儘管這實現起來非常麻煩,但其帶來的優勢也非常大,CoreText 物件建立好後,能直接獲取文字的寬高等資訊,避免了多次計算(調整

UILabel 大小時算一遍、UILabel 繪製時內部再算一遍);CoreText 物件佔用記憶體較少,可以快取下來以備稍後多次渲染。

1.3圖片的解碼

UIImage CGImageSource 的那幾個方法建立圖片時,圖片資料並不會立刻解碼。圖片設定到 UIImageView 或者 CALayer.contents 中去,並且 CALayer 被提交到 GPU 前,CGImage 中的資料才會得到解碼。這一步是發生在主執行緒的,並且不可避免。如果想要繞開這個機制,常見的做法是在後臺執行緒先把圖片繪製到 CGBitmapContext 中,然後從 Bitmap 直接建立圖片。目前常見的網路圖片庫都自帶這個功能。

 1.4影象的繪製

影象的繪製通常是指用那些以 CG 開頭的方法把影象繪製到畫布中,然後從畫布建立圖片並顯示這樣一個過程。這個最常見的地方就是 [UIView drawRect:] 裡面了。由於CoreGraphic 方法通常都是執行緒安全的,所以影象的繪製可以很容易的放到後臺執行緒進行。一個簡單非同步繪製的過程大致如下(實際情況會比這個複雜得多,但原理基本一致):

- (void)display {

dispatch_async(backgroundQueue,^{

CGContextRef ctx =CGBitmapContextCreate(...);

// draw in context...

CGImageRef img =CGBitmapContextCreateImage(ctx);

CFRelease(ctx);

dispatch_async(mainQueue, ^{

layer.contents = img;

});

});

}

可以通過dispatch或者performSelectorInBackground或者NSOperationQueue來實現。

 1.5   I/o操作

        檔案讀寫

        網路

2. 避免後臺載入完成多個資源之後集中到達佔用UI執行緒的處理時間太長。(短時間內UI集中重新整理)

通過NSOperationQueue來實現,將資源到UI的展現過程放在佇列中逐個執行,且在每個操作完成之後進行強制等待,可以用usleep(int microSeconds)來解決。

3.執行緒數太多

原因:

1)大量的任務提交到後臺佇列時,某些任務會因為某些原因被鎖住導致執行緒休眠,或者被阻塞。

      concurrentqueue 隨後會建立新的執行緒來執行其他任務。

當這種情況變多時,或者 App 中使用了大量 concurrent queue 來執行較多工時,App 在同一時刻就會存在幾十個執行緒同時執行、建立、銷燬。

         CPU 是用時間片輪轉來實現執行緒併發的,儘管 concurrent queue 能控制執行緒的優先順序,但當大量執行緒同時建立執行銷燬時,這些操作仍然會擠佔掉主執行緒的 CPU 資源。

2)執行緒數量達到 64個,導致也是導致卡頓的原因。

4 使用lock 時 ,不能Unlock 造成

解決方式: 使用自旋鎖,遞迴鎖。

-(void) dispatch_reentrant(void(^block)())

{

staticNSRecursiveLock *lock = nil;

staticdispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

lock =[[NSRecursiveLock alloc]init];

});

[locklock];

block();

[lockunlock];

}

dispatch_queue_t queueA = dispatch_queue_create("com.queueA", NULL);

dispatch_block_t block = ^{

//do something

};

dispatch_sync(queueA, ^{

dispatch_reentrant(block);

});

5 使用 GCDdispatch_sync 死鎖卡頓

queueA>queueB>queueA

- (void)deadLockFunc

{

dispatch_queue_t queueA =dispatch_queue_create("com.queueA", NULL);

dispatch_queue_t queueB =dispatch_queue_create("com.queueB", NULL);

dispatch_sync(queueA, ^{

dispatch_sync(queueB, ^{

dispatch_block_t block = ^{

//do something

};

func(queueA, block);

});

});

}

解決方式, FMDBAFNetWork 中 採用dispatch_queue_set_specific dispatch_get_specific標記 佇列 ,然後 進行判斷處理,或給出log告警

dispatch_queue_t queueA =dispatch_queue_create("com.queueA", NULL);

dispatch_queue_t queueB =dispatch_queue_create("com.queueB", NULL);

dispatch_set_target_queue(queueB, queueA);

static int specificKey;

CFStringRef specificValue =CFSTR("queueA");

dispatch_queue_set_specific(queueA,

&specificKey,

(void*)specificValue,

(dispatch_function_t)CFRelease);

dispatch_sync(queueB, ^{

dispatch_block_t block = ^{

//do something

};

CFStringRef retrievedValue =dispatch_get_specific(&specificKey);

if (retrievedValue) {

block();

} else {

dispatch_sync(queueA, block);

}

});

6  檢視的混合 

當多個檢視(或者說 CALayer)重疊在一起顯示時,GPU 會首先把他們混合到一起。如果檢視結構過於複雜,混合的過程也會消耗很多 GPU 資源。為了減輕這種情況的 GPU 消耗,應用應當儘量減少檢視數量和層次,並在不透明的視圖裡標明 opaque 屬性以避免無用的 Alpha 通道合成。當然,這也可以用上面的方法,把多個檢視預先渲染為一張圖片來顯示。

7  主執行緒中UI物件建立

物件的建立會分配記憶體、調整屬性、甚至還有讀取檔案等操作,比較消耗 CPU 資源。儘量用輕量的物件代替重量的物件,可以對效能有所優化。

比如 CALayer UIView 要輕量許多,那麼不需要響應觸控事件的控制元件,用 CALayer 顯示會更加合適。如果物件不涉及 UI 操作,則儘量放到後臺執行緒去建立,但可惜的是包含有 CALayer 的控制元件,都只能在主執行緒建立和操作。

·      

參考: http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/

相關推薦

iOS 總結優化

1.除了UI部分,所有的載入操作都在後臺完成。 1.1  文字計算 如果一個介面中包含大量文字,文字的寬高計算會佔用很大一部分資源,並且不可避免。如果你對文字顯示沒有特殊要求,可以參考下 UILabel 內部的實現方式:用 [NSAttributedStringboundi

iOS優化探究學習

1、iOS的CoreAnimation並非只是一些動畫API,本質上是控制圖層的分解、儲存和管理體系。會涉及繪圖、效率等問題。 2、CALayer同UIView類似都是一些被層級關係樹管理的矩形塊,並管理子圖層位置,都可以包含圖片、文字等內容,並有一些API來做動畫。最大的

Android屬性動畫優化

在開發時,在聊天室內用到屬性動畫,時間久了卡頓,先看一下效果圖: 禮物動畫是 SVGA 動畫和屬性動畫配合使用,才達到這樣的效果;這是在聊天室內,會不停的刷這種禮物,在測試時,刷到70個左右,出現明顯的卡頓現象; 為了解決卡頓的問題,去搜了挺多,最終找到了解決的方法; 先看我之前的

iOS監測分析

                                          initWithConfiguration:[[PLCrashReporterConfig alloc] initWithSignalHandlerType:PLCrashReporterSignalHandlerTypeB

簡單監測iOS

本文的demo程式碼也會更新到github上。 做這個demo思路來源於微信team的:微信iOS卡頓監控系統。 主要思路:通過監測Runloop的kCFRunLoopAfterWaiting,用一個子執行緒去檢查,一次迴圈是否時間太長。 其中主要涉及到了runloop的原理。關於整個原理:深入理解RunL

ViewPager 快速切換 --效能優化

當ViewPager切換到當前的Fragment時,Fragment會載入佈局並顯示內容,如果使用者這時快速切換ViewPager,即Fragment需要載入UI內容,而又頻繁地切換Fragment,就容易產生卡頓現象(類似在ListView快速滑動的同時載入圖片容易卡頓)

ios ,push多次同一個頁面

場景:快速多次點選cell跳轉到另一個頁面,另一個頁面被push多次。 原因:push後的頁面有耗時操作或者剛好push到另一個頁面時,另一個頁面正好在reloadData卡住主執行緒。造成點選cell時卡住了。 解決方法: 重寫導航控制器的push方法。 #import

iOS開發之優化tableView現象

1.複用單元格; 2.使用不透明的試圖,單元格中儘量少使用動畫; 3.圖片使用非同步載入同時設定圖片載入的併發數; 4.滑動時不載入圖片,滑動結束開始載入; 5.文字圖片可以直接drawInRect繪製; 6.非必要條件下,減少重新整理的cell; 7.如果ce

App效能優化終極原因研究及總結

熱文導讀 | 點選標題閱讀來源:CoorChicehttps://www.jianshu.com

iOS TableView優化的兩個方法(優化

方法二: 可以利用UIScrollViewDelegate代理很好的解決這問題 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)dece

iOS應用千萬級架構:效能優化監控

CPU和GPU 在螢幕成像的過程中,CPU和GPU起著至關重要的作用 CPU(Central Processing Unit,中央處理器) 物件的建立和銷燬、物件屬性的調整、佈局計算、文字的計算和排版、圖片的格式轉換和解碼、影象的繪製(Core Graphics) GPU(Graphics Processin

android問題及其解決-優化listView和怎樣禁用ListView的fling

cati 依據 過程 none mst 角度 解決問題 ces 開心 問題解決-優化listView卡頓和怎樣禁用ListView的fling 前戲非常長,轉載請保留出處:http://blog.csdn.net/u012123160/ar

關於移動端開發時iOS上滑屏的問題,以及電話類數字的樣式失控問題

img 頁面 通話 tips rem span cti 解法 並不是 寫在前面的話:   tips:寫移動的時候,那些頭部需要固定顯示在顯示屏頂部的,通常在PC端我會用fixed來寫。但是,在移動端,這並不是一個好方法,因為彈出輸入小鍵盤的時候,會造成fixed 的元素偏移

徹底解決 Intellij IDEA 優化筆記,重要的快捷鍵

引入 編譯 今天 ctu ons 文件 使用 com 效率提升 由於工作中經常出現分支各種切換,使用Eclipse便不再像以前那麽舒服了,不停的修改工作空間,每次修改完工作空間又是一堆一堆的個性化設置,來回的切換,真的很累。我們做軟件的,怎麽能不去嘗試新鮮的呢,畢竟,再難走

overflow:scroll 在ios 滾動

加速 scroll 網頁 ssp ios 前端開發 overflow con 應用 使用 -webkit-overflow-scrolling 屬性控制元素在移動設備上是否使用滾動回彈效果. 值 auto   使用普通滾動, 當手指從觸摸屏上移開,滾動會立即停止。 tou

Android 優化 2 渲染優化

運動 發布 Language 嚴重 onresume 背景色 容易 微信 對比 1、概述 2015年初google發布了Android性能優化典範,發了16個小視頻供大家欣賞,當時我也將其下載,通過微信公眾號給大家推送了百度雲的下載地址(地址在文末,ps:歡迎大家訂閱公眾號

Android 優化 3 布局優化

block package 機器 分頁 blog apk scaletype auto 方案 欲善其事, 先利其器. 分析布局, 就不得不用到Hierarchy Viewer了. 本文工具使用皆以GithubApp的詳情界面RepoDetailActivity為例說明

AndroidStudio優化

.com true info 工程 裏的 can lse msi 配置 Xms AS在JVM內存分配方面雞賊的很,縱使你有16G,32G,64G內存,他只給你分配最大幾百兆的堆內存,就會造成工程變大,項目運行時間久後的嚴重卡頓。 優化 打開你的AS安裝目錄,我的是 C:\

iOS探索:UI檢視之、掉幀及繪製原理

在開始理解卡頓、掉幀及繪製原理前,首先讓我們先了解下影象的顯示原理 影象顯示原理 關於CPU和GPU都是通過匯流排連線起來的,在CPU當中輸出的往往是一個位圖,再經由匯流排在合適的時機傳遞個GPU GPU拿到這個點陣圖之後,會對這個點陣圖的圖層進行渲染,包括紋理的合成等

-webkit-overflow-scrolling解決移動端iOS滾動現象

css3中-webkit-overflow-scrolling使用方法 -webkit-overflow-scrolling: touch; //有回彈效果 -webkit-overflow-scrolling: auto; //滑到哪停到哪 實現滾動回彈效果的頁面佈局