iOS_UITableView性能優化

// 提前計算並緩存好高度

// 滑動時按需加載, 防止卡頓 配合SDWebImage https://github.com/johnil/VVeboTableViewDemo

dispatch_async(DISPATCH_QUEUE_PRIORITY_DEFAULT, ^{

    // 異步繪製

});

// 緩存一切可以緩存的

// 默認高度44 定高的cell最好指定高度, 減少不必要的計算

self.tabelView.rowHeight = 88;

// 減少視圖數目

// 減少多餘的繪製操作

// 不給cell動態添加subView 用hidden屬性 控制顯示/隱藏

// 網絡請求, 圖片加載 開啓多線程

// willDisplayCell 可以將數據綁定放在cell顯示出來之後再執行 以提高效率

// 緩存不便於重用的view (存model裏)

// --------   自適應高度   --------

// 儘量提高計算效率, 已計算過的高度需要進行緩存, 沒必要進行第二次運算

// 必須滿足3個條件

// 1. cell.contentView 四邊與內部元素有約束關係(Autolayout)

// 2. 指定estimatedRowHeight屬性的默認值

self.tabelView.estimatedRowHeight = 44;

// 3. 指定rowHeight屬性爲 automatic dimension

self.tabelView.rowHeight = UITableViewAutomaticDimension;

 

// --------   離屏渲染: 圓角/陰影   --------

// 離屏渲染: 圓角/陰影, 另外開闢渲染緩衝區, 消耗性能 (多: 緩衝區頻繁合併 上下文頻繁切換, 導致掉幀)

UIImageView *imgV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"placeholder"]];

imgV.frame = CGRectMake(100, 100, 100, 100);

[self.view addSubview:imgV];

// 優化方案1: (推薦使用) CAShapeLayer UIBezierPath 結合, 可設置單個圓角

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imgV.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:imgV.bounds.size];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];

// 設置大小

maskLayer.frame = imgV.bounds;

// 設置圖形樣子

maskLayer.path = maskPath.CGPath;

imgV.layer.mask = maskLayer;

// 說明: AShapeLayer動畫渲染直接提交到手機的GPU當中,相較於view的drawRect方法使用CPU渲染而言,其效率極高,能大大優化內存使用情況

// 優化方案2: 使用貝塞爾曲線UIBezierPath Core Graphics框架畫出一個圓角

// 開始對imageView進行畫圖

UIGraphicsBeginImageContextWithOptions(imgV.bounds.size, NO, 1.0);

// 使用 貝賽爾曲線 畫出一個圓形圖

[[UIBezierPath bezierPathWithRoundedRect:imgV.bounds cornerRadius:imgV.frame.size.width] addClip];

[imgV drawRect:imgV.bounds];

imgV.image = UIGraphicsGetImageFromCurrentImageContext();

// 結束畫圖

UIGraphicsEndImageContext();

// shadow shadowPath優化

imgV.layer.shadowColor = [UIColor redColor].CGColor;

imgV.layer.shadowOpacity = 0.8;

imgV.layer.shadowRadius = 2.0;

imgV.layer.shadowOffset = CGSizeMake(0, 0);

CGFloat width = 3;

CGRect imgFrame = imgV.bounds;

CGRect shadowFrame = CGRectMake(imgFrame.origin.x - width, imgFrame.origin.y - width, imgFrame.size.width + 2*width, imgFrame.size.height + 2*width);

UIBezierPath *path = [UIBezierPath bezierPathWithRect:shadowFrame];

imgV.layer.shadowPath = path.CGPath;

// 使用異步進行layer渲染(Facebook開源的異步繪製框架AsyncDisplayKit)

// 設置layer的opaque(不透明)值爲YES,減少複雜圖層合成

// 儘量使用不包含透明(alpha)通道的圖片資源

// 儘量設置layer的大小值爲整形值

 

// --------   Core Animation工具檢測離屏渲染   --------

// Xcode->Open Develeper Tools->Instruments

// https://blog.csdn.net/hmh007/article/details/54907560

 

// 可以將數據綁定放在cell顯示出來之後再執行 以提高效率

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

   

}

 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *cellIncdentify = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIncdentify];

    if (!cell) {

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIncdentify];

    }

    // tableView停止滑動的時候異步加載圖片

    if (tableView.dragging == NO && tableView.decelerating == NO) {

        // 開始異步加載圖片

        NSArray *visiblePaths = [tableView indexPathsForVisibleRows];

        for (NSIndexPath *indexPath in visiblePaths) {

            // 獲取dataSource裏的對象, 並且判斷加載完成是不需要再次異步加載

        }

    }

    return cell;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章