iOS性能優化的初步體驗

解決方案

1. 正確使用reuseIdentifier
2. 不要阻塞主線程
3. 重用和延遲加載Views
4. 緩存不容易修改且利用率高的資源
5. 重用開銷大的對象
6. 選擇正確的方式加載本地圖片
7. 使用WKWebView替代UIWebView
8. UITableView 性能優化
9. 處理內存警告
10. 用戶體驗提高

1. 正確使用reuseIdentifierweb

  1. UITableView中UITableViewCell重用
    //1. 註冊(Cell 爲純代碼)
    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell_Reuse"];
    //2. 註冊(Cell 包含Nib 文件)
    [tableView registerNib:[UINib nibWithNibName:@"TalkCell" bundle:nil] forCellReuseIdentifier:@"TalkCell_Reuse"];
    // 根據reuseIdentifier獲取
    [tableView dequeueReusableCellWithIdentifier:@"TalkCell_Reuse" forIndexPath:indexPath];
  2. UITableView中UITableViewHeaderFooterViews的重用,
    UITableViewHeaderFooterViews爲Section的Header或者Footer。
    // 註冊
    [tableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"UITableViewHeaderFooterView_Reuse"];
    // 根據reuseIdentifier獲取
    [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"UITableViewHeaderFooterView_Reuse"];
  3. UICollectionView中UICollectionViewCell重用,同UITableViewCell重用相似
  4. UICollectionView中Supplementary Views重用(追加視圖)相似於UITableView中Section的Header或者Footer.

2. 不要阻塞主線程數據庫

主線程負責UI更新,渲染,用戶交互處理等事件,爲了避免阻塞主線程,除此以外的一些複雜和耗時的操做必須放在子線程中去執行。常見的如獲取網絡資源。緩存

//阻塞主線程
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.baiu.com"]];
//解決方案
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.baiu.com"]];
    });

3. 重用和延遲加載(lazy load)Views性能優化

更多的view意味着更多的渲染,也就是更多的CPU和內存消耗,對於那種嵌套了不少view在UIScrollView裏邊的app更是如此。服務器

  1. 常見的廣告圖瀏覽,或者圖片放大查看器可仿照UITableView或者UICollectionView進行重用,只建立有效數量的View,減小CPU和內存消耗。
  2. 不要一次建立全部的subview,而是當須要時才建立(lazy load/懶加載)。如一個篩選器(當點擊篩選按鈕纔會彈出篩選界面)在效率和內存方面都獲得提高。

4. 緩存不容易修改且利用率高的資源微信

一個極好的原則就是,緩存所須要的,也就是那些不大可能改變可是須要常常讀取的東西。
咱們能緩存些什麼呢?一些選項是,遠端服務器的響應,圖片,甚至計算結果。網絡

  1. 網絡圖片的緩存,如SDWebImage
  2. UITableView Cell 的行高,或者Header/Footer行高等
  3. 數據處理結果。

5. 重用開銷大的對象數據結構

一些對象的初始化很慢,好比NSDateFormatter和NSCalendar。然而,你又不可避免地須要使用它們。那麼能夠把它做爲一個屬性或者是單例來使用。但做爲單例會一直佔用內存。app

6. 選擇正確的方式加載本地圖片框架

  1. 加載常常使用的小圖片
    [UIImage imageNamed:@"hello.png"];
    特色:這個方法用一個指定的名字在系統緩存中查找並返回一個圖片對象若是它存在的話。若是緩存中沒有找到相應的圖片,這個方法從指定的文檔中加載而後緩存並返回這個對象。
    優勢:由於有緩存,第二次加載同一張圖片,則速度更快。
    缺點:有緩存,更多的內存消耗。
  2. 不常常使用,或者大圖片:
    //圖片路徑
     NSString *path = [[NSBundle mainBundle]pathForAuxiliaryExecutable:@"hello.png"];
     //根據路徑加載圖片
     [UIImage imageWithContentsOfFile:path];
    特色:每次都是找到對應路徑的圖片以後再加載圖片,無緩存。

7. 使用WKWebView替代UIWebView

iOS8之後,蘋果推出了新框架Wekkit,提供了替換UIWebView的組件WKWebView。各類UIWebView的問題沒有了,速度更快了,佔用內存少了,一句話,WKWebView是App內部加載網頁的最佳選擇!

8. UITableView 性能優化

  • 正確使用reuseIdentifier來重用cells及Section 的Header 和Footer
  • 若是行高是變化的,則緩存行高,如cell,Section的Header和Footer的行高。
  • 若是行高是固定的,使用使用tableView,rowHeight,
    sectionFooterHeight 和 sectionHeaderHeight來設定固定的高,不用實現代理方法。
  • 若是cell內現實的內容來自web,使用異步加載,緩存請求結果,如圖片等
  • Cell數據資源的緩存,避免重複處理數據。如富文本的多樣化顯示(NSString->NSAttributeString),時間的多樣化現實(2016-01-08 20:40:40 -> 9個月前)

9. 處理內存警告

一旦系統內存太低,iOS會通知全部運行中app。在官方文檔中是這樣記述:
若是你的app收到了內存警告,它就須要儘量釋放更多的內存。最佳方式是移除對緩存,以及一切可再生資源.
幸運的是,UIKit提供了幾種收集低內存警告的方法:

  • 在app delegate中使用applicationDidReceiveMemoryWarning: 的方法
  • 在你的自定義UIViewController的子類(subclass)中覆蓋
    didReceiveMemoryWarning
  • 註冊並接收 UIApplicationDidReceiveMemoryWarningNotification 的通知
    一旦收到這類通知,你就須要釋聽任何沒必要要的內存使用。
    例如,UIViewController的默認行爲是移除一些不可見的view, 它的一些子類則能夠補充這個方法,刪掉一些額外的數據結構。一個有圖片緩存的app能夠移除不在屏幕上顯示的圖片。
    這樣對內存警報的處理是很必要的,若不重視,你的app就可能被系統殺掉。
    必定要在開發中用模擬器中的模擬內存警告。

10. 用戶體驗提高

本地緩存一些用戶常常瀏覽的數據,實現離線瀏覽功能,如微信的朋友圈,微博的首頁等。

  • 使用NSUerDefaults
  • Plist文件
  • 使用NSCoding存檔
  • 使用相似SQLite的本地SQL數據庫
  • 使用 Core Data

NSUserDefaults只適用於小數據,好比一些簡單的布爾型的設置選項。

Plist文件只支持一些簡單的系統類,如NSDictionary,NSArray,NSString等。其餘類就不能用此方法。

NSCoding它須要讀寫文件,當儲存大塊數據或者要支持查詢部分數據,它就沒有任何優點了。

當存儲大塊數據時,以上的方法都不適用. 在這種應用場景下,使用SQLite 或者 Core Data比較好。使用這些技術你用特定的查詢語句就能只加載你須要的對象。 SQLite是iOS內嵌的數據庫,使用C語言的,用SQL語句進行數據操做。 CoreData基於SQLite封裝,OC語言,底層存儲數據的依然是SQLite。

相關文章
相關標籤/搜索