自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入淺出-iOS程序性能優(yōu)化

移動開發(fā) iOS
iOS應(yīng)用是非常注重用戶體驗(yàn)的,不光是要求界面設(shè)計合理美觀,也要求各種UI的反應(yīng)靈敏,我相信大家對那種一拖就卡卡卡的 TableView 應(yīng)用沒什么好印象。

iOS應(yīng)用是非常注重用戶體驗(yàn)的,不光是要求界面設(shè)計合理美觀,也要求各種UI的反應(yīng)靈敏,我相信大家對那種一拖就卡卡卡的 TableView 應(yīng)用沒什么好印象。還記得12306么,那個速度,相信大家都受不了。為了提高 iOS 的運(yùn)行速度,下面我將拋磚引玉介紹一些我實(shí)踐過的用來提供iOS程序運(yùn)行效率的方法,與大家分享,希望能得到更多的反饋和建議。

1,計算代碼運(yùn)行時間:相信數(shù)據(jù),不要太相信感覺。不過要注意模擬器和真機(jī)的差異。

最簡單的工具就是 NSDate,但精度不是太好。

  1. NSDate* tmpStartData = [[NSDate date] retain]; 
  2. //You code here... 
  3. double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData]; 
  4. NSLog(@">>>>>>>>>>cost time = %f", deltaTime); 

或者將運(yùn)行代碼放到如下方法的 block 參數(shù)中,然后返回所運(yùn)行的時間:

  1. #import <mach/mach_time.h>  // for mach_absolute_time() and friends   
  2.    
  3. CGFloat BNRTimeBlock (void (^block)(void)) {   
  4.     mach_timebase_info_data_t info;   
  5.     if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;   
  6.    
  7.     uint64_t start = mach_absolute_time ();   
  8.     block ();   
  9.     uint64_t end = mach_absolute_time ();   
  10.     uint64_t elapsed = end - start;   
  11.    
  12.     uint64_t nanos = elapsed * info.numer / info.denom;   
  13.     return (CGFloat)nanos / NSEC_PER_SEC;   
  14. }  

2,善用性能分析工具。

XCode 自帶了很多強(qiáng)大的分析工具,包括靜態(tài) Analyze 工具,以及運(yùn)行時 Profile 工具。

3,關(guān)于圖片

優(yōu)先使用[UIImage imageNamed:@""];

與[[UIImage alloc] initWithContentsOfFile:] 和 [UIImage alloc [initWithData:]] 相比,[UIImage imageNamed:]有著更好的效率,這是因?yàn)?iOS 會自帶 cache 通過 [UIImage imageNamed:] 載入的圖像,但該方法有一個缺點(diǎn),那就是只能載入應(yīng)用程序 bundle 中的圖像,像網(wǎng)絡(luò)下載的圖像就無能無力了。我習(xí)慣的做法是自定義一個 ImageCache 類,自己來 cache 圖像。

盡量不要使用全屏大小的背景圖片;使用 gradient 圖片來取代硬編碼的 gradient;gradient 圖片應(yīng)當(dāng)盡可能窄,然后將之拉伸運(yùn)用到實(shí)際場合中去。

4,對于結(jié)構(gòu)復(fù)雜的 View,使用 drawRect 自繪而不是從 nib 中載入。

5,對于 TableView,重用 cell;減少 cell 初始化的工作量,延遲裝載;定制復(fù)雜 cell 時,使用 drawRect 自繪;Cache 盡可能多的東西,包括 cell 高度;盡可能讓 cell 不透明;避免使用圖像特性,比如 gradients。

6,在線程中使用 autoreleasepool。

7,將一些不太重要的任務(wù)放在 idle 時運(yùn)行。

  1. - (void)idleNotificationMethod { 
  2.     // do something here 
  3.  
  4. - (void)registerForIdleNotification  
  5.     [[NSNotificationCenter defaultCenter] addObserver:self 
  6.         selector:@selector(idleNotificationMethod) 
  7.         name:@"IdleNotification" 
  8.         object:nil]; 
  9.     NSNotification *notification = [NSNotification 
  10.         notificationWithName:@"IdleNotification" object:nil]; 
  11.     [[NSNotificationQueue defaultQueue] enqueueNotification:notification 
  12.       postingStyle:NSPostWhenIdle]; 
  13. }  

8,不要在 viewWillAppear 中做費(fèi)時的操作。

viewWillAppear: 在 view 顯示之前被調(diào)用,出于效率考慮,在這個方法中不要處理復(fù)雜費(fèi)時的事情;只應(yīng)該在這個方法設(shè)置 view 的顯示屬性之類的簡單事情,比如背景色,字體等。要不然,用戶會明顯感覺到 view 顯示遲鈍。

9,使用多線程來延遲加載資源。比如常見的 TableViewCell 中的網(wǎng)絡(luò)圖像顯示,先使用一個默認(rèn)圖像,然后開啟線程下載網(wǎng)絡(luò)圖像,當(dāng)圖像下載完成之后,再替換默認(rèn)圖像。

10,關(guān)于后臺任務(wù)

系統(tǒng)進(jìn)入 background 之后,一般只有10分鐘的運(yùn)行時間,因此有很多值得注意的事項(xiàng):

  • a) 盡量減少內(nèi)存的使用。當(dāng)內(nèi)存不足時,iOS將kill那些消耗內(nèi)存最多的 App。
  • b) 釋放所有的共享資源,比如 Calendar 與 Address book。當(dāng)應(yīng)用程序進(jìn)入后臺時,如果它還在使用或沒有釋放共享資源,iOS會立即kill掉該應(yīng)用程序。
  • c) 正確處理App生命周期事件。當(dāng)進(jìn)入后臺時,應(yīng)該保持應(yīng)用程序數(shù)據(jù),以便回到前臺時能夠恢復(fù)。當(dāng)進(jìn)入 inactive 狀態(tài)時,應(yīng)該暫停當(dāng)前的業(yè)務(wù)流。iOS運(yùn)行App在后臺運(yùn)行的時間有限,因此后臺代碼不應(yīng)該執(zhí)行非常耗時的任務(wù),可能的話就使用多線程。當(dāng)進(jìn)入后臺 時,iOS會保存當(dāng)前App的一個快照,以便之后在合適的時候(裝載view和數(shù)據(jù)時)呈現(xiàn)給用戶以提高用戶體驗(yàn),因此在進(jìn)入后臺時,應(yīng)該避免在屏幕上呈 現(xiàn)用戶信息,以免泄露用戶個人資料。
  • d) 不要更新UI或者執(zhí)行大量消耗CPU或電池的代碼。進(jìn)入后臺之后,不應(yīng)該執(zhí)行不必要的任務(wù),不要執(zhí)行 OpenGL ES 調(diào)用,應(yīng)取消 Bonjour 相關(guān)的服務(wù),正確處理網(wǎng)絡(luò)鏈接失敗,避免更新 UI,清除所有的警告或其他彈出對話框。
  • e) 保證后臺代碼的執(zhí)行工作正常,注意處理異常。
  • f) 在后臺時正確響應(yīng)系統(tǒng)變化。 如: 設(shè)備旋轉(zhuǎn)消息UIDeviceOrientationDidChangeNotification ,重要的時間變化(新的一天開始或時區(qū)變化)UIApplicationSignificantTimeChangeNotification ,電池變化UIDeviceBatteryLevelDidChangeNotification 和 UIDeviceBatteryStateDidChangeNotification,用戶默認(rèn)設(shè)置變化 NSUserDefaultsDidChangeNotification,本地化語言變化 NSCurrentLocaleDidChangeNotification 等。

11,如果關(guān)鍵代碼使用 C/C++/asm 效率更高就使用 C/C++/asm。

12,如果一個方法在一個循環(huán)次數(shù)非常多的循環(huán)中使用,在進(jìn)入循環(huán)前使用 methodForSelector 獲取該方法 IMP,然后在循環(huán)體中直接使用該 IMP。

13,關(guān)于內(nèi)存釋放

在 didReceiveMemoryWarning 中釋放內(nèi)存,比如cache 的圖像,view 等,并記得調(diào)用 [supper didReceiveMemoryWarning]。清理函數(shù) didReceiveMemoryWarning, viewDidUnload 和 dealloc 都是在方法結(jié)尾處調(diào)用 supper 的方法。

14,提高 APP 加載速度

避免使用靜態(tài)初始化,包括靜態(tài)c++對象,加載時會運(yùn)行的代碼,如+(void) load{} ,會造成在Main函數(shù)之前運(yùn)行額外的代碼。

16,利用 cache 空間換時間。cache 是一種常見的空間換時間的提供性能的收到,可以用在相當(dāng)多的場合。

盡量 cache 那些可重復(fù)利用的對象,比如 table cell,date/number formatters,正則表達(dá)式,sqlite語句等。

17,關(guān)于數(shù)據(jù)庫

緩存經(jīng)常用到的 sqlite 語句;優(yōu)化數(shù)據(jù)庫查詢語句,用sqlite3_trace和sqlite3_profile來查找性能差的語句;如果可能的話,緩存查詢結(jié)果緩。

在使用 sqlite_prepare會將SQL查詢編譯成字節(jié)碼,要使用bind,重用那些已經(jīng)prepared的語句。

責(zé)任編輯:張葉青 來源: 博客
相關(guān)推薦

2024-12-09 09:50:00

JVM逃逸逃逸分析

2011-07-04 10:39:57

Web

2010-08-27 09:44:07

無線網(wǎng)絡(luò)性能

2021-03-16 08:54:35

AQSAbstractQueJava

2022-09-26 09:01:15

語言數(shù)據(jù)JavaScript

2017-07-02 18:04:53

塊加密算法AES算法

2019-01-07 15:29:07

HadoopYarn架構(gòu)調(diào)度器

2021-07-20 15:20:02

FlatBuffers阿里云Java

2012-05-21 10:06:26

FrameworkCocoa

2009-11-17 17:31:58

Oracle COMM

2010-07-16 09:11:40

JavaScript內(nèi)存泄漏

2021-07-19 11:54:15

MySQL優(yōu)先隊(duì)列

2023-12-04 13:22:00

JavaScript異步編程

2010-07-26 12:57:12

OPhone游戲開發(fā)

2016-10-14 13:53:05

JavascriptDOMWeb

2016-10-14 14:32:58

JavascriptDOMWeb

2024-01-09 12:05:24

SSH協(xié)議端口

2009-11-30 16:46:29

學(xué)習(xí)Linux

2022-01-11 07:52:22

CSS 技巧代碼重構(gòu)

2019-11-11 14:51:19

Java數(shù)據(jù)結(jié)構(gòu)Properties
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號