tableView優化思路

通常優化的思路:緩存

  1. 提早計算並緩存好高度(佈局),由於heightForRowAtIndexPath:是調用最頻繁的方法。網絡

  2. 複雜界面可採用異步繪製。多線程

  3. 在大量圖片展現時,能夠滑動時按需加載。異步

  4. 儘可能少用或不用透明圖層,多個透明元素重疊顯示可採用合併成一張圖片顯示。async

  5. 減小subviews的數量,若是是不須要交互可使用CALayer 替換掉 UIView。ide

  6. heightForRowAtIndexPath:中儘可能不使用cellForRowAtIndexPath:oop

  7. 根據場景合理使用imageWithContentsOfFile和imageNamed。佈局

  8. 頁面元素多的時候,減小autolayout佈局,採用frame。優化

  9. 緩存NSDateFormatter結果,很少次建立,及時釋放。spa

  10. 圖片解碼時,CALayer 被提交到 GPU 前,CGImage 中的數據纔會獲得解碼,GPU執行,卡主線程。常見的作法是在後臺線程先把圖片繪製到 CGBitmapContext 中,而後從 Bitmap 直接建立圖片。

  11. CALayer 的 border、圓角、陰影、遮罩(mask)觸發的離屏渲染,可開啓CALayer.shouldRasterize ,轉嫁到CPU上或是截圖或者採用圖片實現。

  12. 使用RunLoop和多線程在閒時處理一些繁重的計算工做。

緩存高度

提早計算好 cell 的高度和佈局

// 關於UITableView有兩個重要的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

iOS8後,會邊滑動邊調用heightForRowAtIndexPath:這個方法; 想一想一下, 若是把計算cell高度的方法寫在這兒, 不只每次都會調用計算方法, 並且重複滑動的話, 還會再次計算; 因此咱們通常在網絡請求結束後,更新界面以前就把每一個 cell 的高度算好,緩存到相對應的 model 中。

異步繪製

在Cell上添加系統控件的時候,實質上系統都須要調用底層的接口進行繪製,當咱們大量添加控件時,對資源的開銷也會很大,因此咱們能夠索性直接繪製,提升效率。

//異步繪製
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    CGRect rect = CGRectMake(0, 0, 100, 100);
    UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [[UIColor lightGrayColor] set];
    CGContextFillRect(context, rect);

    //將繪製的內容以圖片的形式返回,並調主線程顯示
    UIImage *temp = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // 回到主線程
    dispatch_async(dispatch_get_main_queue(), ^{
        //code
    });
});

減小層級

減小SubViews的數量, 在滑動的列表上,多層次的view會致使幀數的降低。
例如: 繪製 cell 不建議使用 UIView,建議使用 CALayer。
從形式來講:UIView 的繪製是創建在 CoreGraphic 上的,使用的是 CPU。CALayer 使用的是 Core Animation,CPU,GPU 通吃,由系統決定使用哪一個。View的繪製使用的是自下向上的一層一層的繪製,而後渲染。Layer處理的是 Texure,利用 GPU 的 Texture Cache 和獨立的浮點數計算單元加速 紋理 的處理。

從事件的響應來講:UIView是 CALayer 的代理,layer自己並不能響應事件,由於layer是直接繼承自NSObject,不具有處理事件的能力。而 UIView 是繼承了UIResponder 的,這也是事件轉發的角度上說明,view要比單純的layer複雜的多。多層次的view再加上各類手勢的處理勢必致使幀數的降低。

hide

儘可能少用addView給Cell動態添加View,能夠初始化時就添加,而後經過hide來控制是否顯示

避免離屏渲染

爲了保證TableView的流暢,當快速滑動的時候,cell必須被快速的渲染出來。因此cell渲染的速度必須快。如何提升cell的渲染速度呢?

  • 當有圖像時,預渲染圖像,在bitmap context先將其畫一遍,導出成UIImage對象,而後再繪製到屏幕,這會大大提升渲染速度。具體內容能夠自行查找「利用預渲染加速顯示iOS圖像」相關資料。
  • 渲染最好時的操做之一就是混合(blending)了,因此咱們不要使用透明背景,將cell的opaque值設爲Yes,背景色不要使用clearColor,儘可能不要使用陰影漸變等
  • 因爲混合操做是使用GPU來執行,咱們能夠用CPU來渲染,這樣混合操做就再也不執行。能夠在UIView的drawRect方法中自定義繪製。

固然除了這些, 還有其餘的優化方法:

  • 正確地使用UITableViewCell的重用機制
  • 避免阻塞主線程
  • 按需加載
  • 儘量重用開銷比較大的對象
  • 儘可能減小計算的複雜度
相關文章
相關標籤/搜索