tableView性能优化


cell重用

  • 1 定义ID

  • 2 初始化

//tabview 初始化
- (UITableView*)TabView{
    if (!_TabView) {
        UITableView* v = [[UITableView alloc]init];
        v.delegate = self;
        v.dataSource = self;        
        // 右侧指示器设置
        v.sectionIndexBackgroundColor = [UIColor clearColor];
        v.sectionIndexColor = PKSecondaryTextColor;
        v.sectionIndexMinimumDisplayRowCount = 0;        
        // 不显示分割线
        v.separatorStyle = UITableViewCellSeparatorStyleNone;  
        [v registerClass:[PKCreateCircleAddFriendHeadCell class] forCellReuseIdentifier:@"head"];
        [v registerNib:[UINib nibWithNibName:NSStringFromClass([PKCreateCircleAddFriendSeeCell class]) bundle:nil] forCellReuseIdentifier:@"body"];               
        _TabView = v;
    }
    return _TabView;
}

//cell 初始化
@implementation PKCreateCircleAddFriendHeadCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self setup];
    }
    return self;    
}
@end


//xib cell 初始化
@implementation PKCreateCircleAddFriendSeeCell
#pragma mark - Life cycle.生命周期方法
- (void)awakeFromNib {
    // Initialization code
    [self setup];
}
+ (instancetype)PKCreateCircleAddFriendSeeCell{
    return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] firstObject];
}
@end
  • 3 Id对应物件不存在重新创建
    static NSString *cellIdentifer = @"cell";
    //先去缓存池中查找是否有满足条件的Cell
    AJPhotoGroupCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifer forIndexPath:indexPath];
    //如果缓存池中没有符合条件的cell,就自己创建一个Cell
    if(cell == nil){
        cell = [[AJPhotoGroupCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifer];
    }

注意


  • 1先去缓存池中查找是否有满足条件的cell,若有那就直接拿来
  • 2若没有,就自己创建一个cell
  • 3创建cell,并且设置一个唯一的标记(把属于“”的给盖个章)
  • 4给cell设置数据

注意点: 定义变量用来保存重用标记的值,这里不推荐使用宏(#define来处理),因为该变量只在这个作用域的内部使用,且如果使用宏定义的话,定义和使用位置太分散,不利于阅读程序。由于其值不变,没有必要每次都开辟一次,所以用static定义为一个静态变量。

分段加载


判断开始更新范围

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (count - indexPath.row < 10 && !updating) {
        updating = YES;
        [self update];
    }
}

加载新数据


NSArray *indexPaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *visibleIndexPath in indexPaths) {
    if (indexPath == visibleIndexPath) {
        MyTableViewCell *cell = (MyTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        cell.image = image;
        [cell setNeedsDisplayInRect:imageRect];
        break;
    }
}

刷新方式


全部刷新

最后还是前面所说过的insertRowsAtIndexPaths:withRowAnimation:方法,插入新行需要在主线程执行,而一次插入很多行的话(例如50行),会长时间阻塞主线程。而换成reloadData方法的话,瞬间就处理完了。

[self.tableView reloadData];

单行刷新

//1直接刷新
[tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
//2处理后刷新
[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:2], [NSIndexPath indexPathForRow:4 inSection:2]] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:2], [NSIndexPath indexPathForRow:4 inSection:2]] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:2 inSection:2]] withRowAnimation:UITableViewRowAnimationFade];