iOS 性能優化方面的面試題
這是我前面幾天碰到的面試題:
如何對定位和分析項目中影響性能的地方?以及如何進行性能優化?
我的答案:
定位方法:
instruments
在iOS上進行性能分析的時候,首先考慮借助instruments這個利器分析出問題出在哪,不要憑空想象,不然你可能把精力花在了1%的問題上,最後發現其實啥都沒優化,比如要檢視程式哪些部分最耗時,可以使用Time Profiler,要檢視記憶體是否洩漏了,可以使用Leaks等。關于instruments網上有很多資料,作為一個合格iOS開發者,熟悉這個工具還是很有必要的。
作為一個開發者,有一個學習的氛圍跟一個交流圈子特别重要,這是一個我的iOS交流群:638302184,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿裡面試題、面試經驗,讨論技術, 大家一起交流學習成長!希望幫助開發者少走彎路。
優化建議:
1.用ARC管理記憶體
- ARC(Automatic Reference Counting, 自動引用計數)和iOS5一起釋出,它避免了最常見的也就是經常是由于我們忘記釋放記憶體所造成的記憶體洩露。它自動為你管理retain和release的過程,是以你就不必去手動幹預了。下面是你會經常用來去建立一個View的代碼段: UIView *view = [[UIView alloc] init];
- // ...
- [self.view addSubview:view];
- [view release];
- 忘掉代碼段結尾的release簡直像記得吃飯一樣簡單。而ARC會自動在底層為你做這些工作。除了幫你避免記憶體洩露,ARC還可以幫你提高性能,它能保證釋放掉不再需要的對象的記憶體。這都啥年代了,你應該在你的所有項目裡使用ARC!
2.在正确的地方使用 reuseIdentifier
- 一個開發中常見的錯誤就是沒有給UITableViewCells, UICollectionViewCells,甚至是UITableViewHeaderFooterViews設定正确的reuseIdentifier。
- 為了性能最優化,table view用 tableView:cellForRowAtIndexPath: 為rows配置設定cells的時候,它的資料應該重用自UITableViewCell。 一個table view維持一個隊列的資料可重用的UITableViewCell對象。不使用reuseIdentifier的話,每顯示一行table view就不得不設定全新的cell。這對性能的影響可是相當大的,尤其會使app的滾動體驗大打折扣。
- 自iOS6起,除了UICollectionView的cells和補充views,你也應該在header和footer views中使用reuseIdentifiers
3.盡量把views設定為完全不透明
- 如果你有透明的Views你應該設定它們的opaque(不透明)屬性為YES。例如一個黑色半透明的可以設定為一個灰色不透明的View替代.原因是這會使系統用一個最優的方式渲染這些views。這個簡單的屬性在IB或者代碼裡都可以設定。
- Apple的文檔對于為圖檔設定透明屬性的描述是:
- (opaque)這個屬性給渲染系統提供了一個如何處理這個view的提示。如果設為YES, 渲染系統就認為這個view是完全不透明的,這使得渲染系統優化一些渲染過程和提高性能。如果設定為NO,渲染系統正常地和其它内容組成這個View。預設值是YES。
- 在相對比較靜止的畫面中,設定這個屬性不會有太大影響。然而當這個view嵌在scroll view裡邊,或者是一個複雜動畫的一部分,不設定這個屬性的話會在很大程度上影響app的性能。
- 換種說法,大家可能更好了解:隻要一個視圖的不透明度小于1,就會導緻blending.blending操作在iOS的圖形處理器(GPU)中完成的,blending主要指的是混合像素顔色的計算。舉個例子,我們把兩個圖層疊加在一起,如果第一個圖層的有透明效果,則最終像素的顔色計算需要将第二個圖層也考慮進來。這一過程即為Blending。為什麼Blending會導緻性能的損失?原因是很直覺的,如果一個圖層是完全不透明的,則系統直接顯示該圖層的顔色即可。而如果圖層是帶透明效果的,則會引入更多的計算,因為需要把下面的圖層也包括進來,進行混合後顔色的計算。
- 避免過于龐大的XIB
- iOS5中加入的Storyboards(分鏡)正在快速取代XIB。然而XIB在一些場景中仍然很有用。比如你的app需要适應iOS5之前的裝置,或者你有一個自定義的可重用的view,你就不可避免地要用到他們。
- 如果你不得不XIB的話,使他們盡量簡單。嘗試為每個Controller配置一個單獨的XIB,盡可能把一個View Controller的view層次結構分散到單獨的XIB中去。
- 需要注意的是,當你加載一個XIB的時候所有内容都被放在了記憶體裡,包括任何圖檔。如果有一個不會即刻用到的view,你這就是在浪費寶貴的記憶體資源了。Storyboards就是另一碼事兒了,storyboard僅在需要時執行個體化一個view controller.
- 當你加載一個引用了圖檔或者聲音資源的nib時,nib加載代碼會把圖檔和聲音檔案寫進記憶體。在OS X中,圖檔和聲音資源被緩存在named cache中以便将來用到時擷取。在iOS中,僅圖檔資源會被存進named caches。取決于你所在的平台,使用NSImage 或UIImage 的imageNamed:方法來擷取圖檔資源。
- 不要阻塞主線程
- 永遠不要使主線程承擔過多。因為UIKit在主線程上做所有工作,渲染,管理觸摸反應,回應輸入等都需要在它上面完成。一直使用主線程的風險就是如果你的代碼真的block了主線程,你的app會失去反應
- 大部分阻礙主程序的情形是你的app在做一些牽涉到讀寫外部資源的I/O操作,比如存儲或者網絡。或者使用像 AFNetworking這樣的架構來異步地做這些操作。如果你需要做其它類型的需要耗費巨大資源的操作(比如時間敏感的計算或者存儲讀寫)那就用 Grand Central Dispatch,或者 NSOperation 和 NSOperationQueues.你可以使用NSURLConnection異步地做網絡操作: + (void)sendAsynchronousRequest:(NSURLRequest )request queue:(NSOperationQueue )queue completionHandler:(void (^)(NSURLResponse, NSData, NSError*))handler
- 在Image Views中調整圖檔大小
- 如果要在UIImageView中顯示一個來自bundle的圖檔,你應保證圖檔的大小和UIImageView的大小相同。在運作中縮放圖檔是很耗費資源的,特别是UIImageView嵌套在UIScrollView中的情況下。
- 如果圖檔是從遠端服務加載的你不能控制圖檔大小,比如在下載下傳前調整到合适大小的話,你可以在下載下傳完成後,最好是用background thread,縮放一次,然後在UIImageView中使用縮放後的圖檔。
- 選擇正确的Collection
學會選擇對業務場景最合适的類或者對象是寫出能效高的代碼的基礎。當處理collections時這句話尤其正确。
Apple有一個 Collections Programming Topics 的文檔詳盡介紹了可用的classes間的差别和你該在哪些場景中使用它們。這對于任何使用collections的人來說是一個必讀的文檔。
呵呵,我就知道你因為太長沒看…這是一些常見collection的總結:
- Arrays: 有序的一組值。使用index來lookup很快,使用value lookup很慢, 插入/删除很慢。
- Dictionaries: 存儲鍵值對。 用鍵來查找比較快。
- Sets: 無序的一組值。用值來查找很快,插入/删除很快。
- 打開gzip壓縮
- 大量app依賴于遠端資源和第三方API,你可能會開發一個需要從遠端下載下傳XML, JSON, HTML或者其它格式的app。
- 問題是我們的目标是移動裝置,是以你就不能指望網絡狀況有多好。一個使用者現在還在edge網絡,下一分鐘可能就切換到了3G。不論什麼場景,你肯定不想讓你的使用者等太長時間。
-
減小文檔的一個方式就是在服務端和你的app中打開gzip。這對于文字這種能有更高壓縮率的資料來說會有更顯著的效用。好消息是,iOS已經在NSURLConnection中預設支援了gzip壓縮,當然AFNetworking這些基于它的架構亦然。像Google App Engine這些雲服務提供者也已經支援了壓縮輸出。
原文位址
https://www.cnblogs.com/Mcci7/p/10739293.html