25個增強iOS應用程式效能的提示和技巧(初級篇)

來源:互聯網
上載者:User

在開發iOS應用程式時,讓程式具有良好的效能是非常關鍵的。這也是使用者所期望的,如果你的程式運行遲鈍或緩慢,會招致使用者的差評。然而由於iOS裝置的局限性,有時候要想獲得良好的效能,是很困難的。在開發過程中,有許多事項需要記住,並且關於效能影響很容易就忘記。

 

本文收集了25個關於可以提升程式效能的提示和技巧,把效能最佳化技巧分為3個不同的等級:初級、中級和進階

 

初級

在開發過程中,下面這些初級技巧需要時刻注意:

 

1.使用ARC進行記憶體管理

2.在適當的情況下使用reuseIdentifier

3.儘可能將View設定為不透明(Opaque)

4.避免臃腫的XIBs

5.不要阻塞主線程

6.讓圖片的大小跟UIImageView一樣

7.選擇正確的集合

8.使用GZIP壓縮

 

1) 使用ARC進行記憶體管理

ARC是在iOS 5中發布的,它解決了最常見的記憶體泄露問題——也是開發人員最容易健忘的。ARC的全稱是“Automatic Reference Counting”——自動引用計數,它會自動的在代碼中做retain/release工作,開發人員不用再手動處理。

 

下面是建立一個View通用的一些代碼塊:

1.UIView *view = [[UIView alloc] init];

2.// ...

3.[self.view addSubview:view];

4.[view release];

 

在上面代碼結束的地方很容易會忘記調用release。不過當使用ARC時,ARC會在後台自動的幫你調用release。

 

ARC除了能避免記憶體泄露外,還有助於程式效能的提升:當程式中的對象不再需要的時候,ARC會自動銷毀對象。所以,你應該在工程中使用ARC。

 

下面是學習ARC的一些資源:

蘋果的官方文檔


Matthijs Hollemans的初級ARC



Tony Dahbura的如何在Cocos2D 2.X工程中使用ARC



如果你仍然不確定ARC帶來的好處,那麼看一些這篇文章:8個關於ARC的神話——這能夠讓你相信你應該在工程中使用ARC!



值得注意的是,ARC並不能避免所有的記憶體泄露。使用ARC之後,工程中可能還會有記憶體泄露,不過引起這些記憶體泄露的主要原因是:block,retain迴圈,對CoreFoundation對象(通常是C結構)管理不善,以及真的是代碼沒寫好。



這裡有一篇文章是介紹哪些問題是ARC不能解決的
— 以及如何處理這些問題。

 

2) 在適當的情況下使用reuseIdentifier



在適當的情況使用reuseIdentifier

在iOS程式開發中一個普遍性的錯誤就是沒有正確的為UITableViewCells、UICollectionViewCells和UITableViewHeaderFooterViews設定reuseIdentifier。 

為了獲得最佳效能,當在tableView:cellForRowAtIndexPath:方法中返回cell時,table view的資料來源一般會重用UITableViewCell對象。table view維護著UITableViewCell對象的一個隊列或者列表,這些資料來源已經被標記為重用了。

 

如果沒有使用reuseIdentifier會發生什嗎?如果你在程式中沒有使用reuseIdentifier,table view每次顯示一個row時,都會配置一個全新的cell。這其實是一個非常消耗資源的操作,並且會影響程式中table view滾動的效率。

 

自iOS 6以來,你可能還希望header和footer views,以及UICollectionView的cell和supplementary views。

 

為了使用reuseIdentifiers,在table view請求一個新的cell時,在資料來源中調用下面的方法:

1.static NSString *CellIdentifier = @"Cell";

2.UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

 

如果table view維護的UITableViewCell隊列或列表中有可用的cell,則從隊列從移除一個已經存在的cell,如果沒有的話,就從之前註冊的nib檔案或類中建立一個新的cell。如果沒有可以重用的cell,並且沒有註冊nib檔案或類,tableview的dequeueReusableCellWithIdentifier:方法會返回一個nil。


3) 儘可能將View設定為不透明(Opaque)



盡量將view設定為Opaque

 

如果view是不透明的,那麼應該將其opaque屬性設定為YES。為什麼要這樣做呢?這樣設定可以讓系統以最優的方式來繪製view。opaque屬性可以在Interface Builder或代碼中設定。

 

蘋果的官方文檔對opaque屬性有如下解釋:

This property provides a hint to the drawing system as to how it should treat the view. If set to YES, the drawing system treats the view as fully opaque, which allows the drawing system to optimize
some drawing operations and improve performance. If set to NO, the drawing system composites the view normally with other content. The default value of this property is YES.

(opaque屬性提示繪製系統如何處理view。如果opaque設定為YES,繪圖系統會將view看為完全不透明,這樣繪圖系統就可以最佳化一些繪製操作以提升效能。如果設定為NO,那麼繪圖系統結合其它內容來處理view。預設情況下,這個屬性是YES。)

 

如果螢幕是靜止的,那麼這個opaque屬性的設定與否不是一個大問題。但是,如果view是嵌入到scroll view中的,或者是複雜動畫的一部分,不將設定這個屬性的話肯定會影響程式的效能!可以通過模擬器的Debug\Color Blended Layers選項來查看哪些view沒有設定為不透明。為了程式的效能,儘可能的將view設定為不透明!

 

4) 避免臃腫的XIBs



避免臃腫的XIBs

 

在iOS 5中開始使用Storyboards,並且將替代XIBs。不過在有些情況下XIBs仍然有用。如果你的程式需要運行在裝有iOS 5之前版本的裝置上,或者要自訂可重用的view,那麼是避免不了要使用XIBs的。

 

如果必須要使用XIBs的話,盡量讓XIBs檔案簡單。並且每個view controller對於一個XIB檔案,如果可以的話,把一個view controller的view不同的層次單獨分到一個XIBs檔案中。

 

(注意:當把一個XIB檔案載入到記憶體時,XIB檔案中的所有內容都將被載入到記憶體中,包括圖片。如果有一個view還不立即使用的話,就會造成記憶體的浪費。而這在storyboard中是不會發生的,因為storyboard還在需要的時候才執行個體化一個view controller。)

 

當載入XIB時,所有涉及到的圖片都將被緩衝,並且如果是開發的程式是針對OS X的話,音效檔也會被載入。蘋果的官方文檔這樣說:

When you load a nib file that contains references to image or sound resources, the nib-loading code reads the actual image or sound file into memory and and caches it. In OS X, image and sound resources
are stored in named caches so that you can access them later if needed. In iOS, only image resources are stored in named caches. To access images, you use the imageNamed: method of NSImage or UIImage, depending on your platform.

(當載入一個nib檔案時,也會將nib檔案涉及到的圖片或聲音資源載入到記憶體中,nib-loading代碼會將實際的圖片或音效檔讀取到記憶體中,並一直緩衝著。在OS X中,圖片和聲音資源都儲存在具名快取中,這樣之後如果需要的話,可以對其進行訪問。在iOS中,只有圖片資源被儲存到具名快取中。要訪問圖片的話,使用NSImage或UIImage(根據不同的系統)的imageNamed:方法即可。)

 

顯然,在使用storyboard時也會發生類似的快取作業;不過我沒有找到相關內容的任何資料。想要學習storyboard的更多知識嗎?可以看看Matthijs Hollemans寫的iOS 5中:初級Storyboard
Part 1和Part2。

 

5) 不要阻塞主線程



永遠都不要在主線程做繁重的任務。因為UIKit的左右任務都在主線程中進行,例如繪製、觸摸管理和輸入響應。 

在主線程做所有任務的風險是:如果你的代碼阻塞了主線程,那麼程式將出現反應遲鈍。這回招致使用者在App Store上對程式的差評!

 

在執行I/O操作中,大多數情況下都會祖塞主線程,這些操作需要從讀寫外部資源,例如磁碟或者網路。

 

關於網路操作可以使用NSURLConnection的如下方法,以非同步方式來執行:

1.+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void
(^)(NSURLResponse*, NSData*, NSError*))handler

或者使用第三方架構,例如AFNetworking。

 

如果你需要做一些其它類型開銷很大的操作(例如執行一個時間密集型的計算或者對磁碟進行讀寫),那麼就使用GCD(Grand Central Dispatch),或NSOperations 和 NSOperationQueues。

 

下面的代碼是使用GCD的一個模板:

1.dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

2.    // switch to a background thread and perform your expensive operation

3.

4.    dispatch_async(dispatch_get_main_queue(), ^{

5.        // switch back to the main thread to update your UI

6.

7.    });

8.});

如上代碼,為什麼在第一個dispatch_async裡面還嵌套了一個dispatch_async呢?這是因為關於UIKit相關的代碼需要在主線程裡面執行。

可以看看Ray Wenderlich中的教程:iOS中多線程和GCD—初級,以及Soheil
Azarpour的如何使用NSOperations和NSOperationQueues教程。

 

6) 讓圖片的大小跟UIImageView一樣



確保圖片和UIImageView大小一致

如果需要將程式bundle中的圖片顯示到UIImageView中,請確保圖片和UIImageView的大小是一樣的。因為圖片的縮放非常耗費資源,特別是將UIImageView嵌入到UIScrollView中。

如果是從遠程服務中下載圖片,有時候你控制不了圖片的尺寸,或者在下載之前無法在伺服器上進行圖片的縮放。這種情況,當圖片下載完之後,你可以手動進行圖片的縮放——做好是在後台線程中!——然後再在UIImageView中使用縮放過的圖片。

 

 
7) 選擇正確的集合



選擇正確的集合

學習使用最適合的類或對象是編寫高效代碼的基礎。特別是在處理集合資料時,尤為重要。

蘋果的官網上有一篇文章:集合編程主題(Collections
Programming Topics)——詳細的介紹了在集合資料中可以使用的類,以及什麼情況下使用哪個類。在使用集合時,每個開發人員都應該閱讀一下這個文檔。

太長,不想閱讀(TLDR)?下面是常見集合類型的一個簡介:

•數組:是一個值按順序排列的一個列表。根據索引可以快速尋找,不過根據值進行尋找就比較慢,另外插入和刪除也比較慢。

•字典:  儲存鍵/值對。根據鍵可以快速尋找。

•Sets:  是一個值無序排列的列表,根據值可以快速尋找,另外插入和刪除也比較快。 

8) 使用GZIP壓縮



使用GZIP壓縮



越來越多的程式依賴於外部資料,這些資料一般來自遠程伺服器或者其它的外部APIs。有時候你需要開發一個程式來下載一些資料,這些資料可以是XML,JSON,HTML或者其它一些文字格式設定。

 

問題是在行動裝置上的網路是不確定的。使用者的裝置可能在EDGE網路一分鐘,然後接著又在3G網路中。不管在什麼情況下,都不要讓使用者等待。

 

有一個可以最佳化的選擇:使用GZIP對網路傳輸中的資料進行壓縮,這樣可以減小檔案的大小,並加快下載的速度。壓縮對於文本資料特別有用,因為文本具有很高的壓縮比。

 

iOS中,如果使用NSURLConnection,那麼預設情況下已經支援GZIP壓縮了,並且基於NSURLConnection的架構頁支援GZIP壓縮,如AFNetworking。甚至有些雲端服務供應商已經提供發送經壓縮過的響應內容,例如

Google App Engine。

 

這裡有一篇關於GZIP壓縮很好的文章,介紹了如何在Apache活IIS伺服器中開啟支援GZIP壓縮。

 

 

 

來源:破船的部落格

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.