UITableView优化

UITableView 的优化主要从以下3个方面分析:

  • 基础的优化准则(高度缓存, cell 重用…)
  • 学会使用调试工具分析问题
  • 异步绘制

基础的优化准则

1、正确地使用UITableViewCell的重用机制

UITableView最核心的思想就是 UITableViewCell 的重用机制。UITableView 只会创建一屏幕(或一屏幕多一点)的 UITableViewCell ,每当 cell 滑出屏幕范围时,就会放入到一重用池当中,当要显示新的 cell 时,先去重用池中取,若没有可用的,才会重新创建。这样可以极大的减少内存的开销。

2、提前计算好 cell 的高度和布局。

UITableView有两个重要的回调方法:

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

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

UITableView的回调顺序是先多次调用tableView:heightForRowAtIndexPath:用来确定 contentSizeCell的位置,然后才会调用 tableView:cellForRowAtIndexPath:,从而来显示在当前屏幕的 cell 。
iOS8会更厉害,还会边滑动边调用 tableView:heightForRowAtIndexPath:,可见这个方法里一定不能重复进行着大量的计算。我们应该提前计算好 cell 的高度并且缓存起来,在回调时直接把高度值直接返回。

这里说一种我经常采用的策略:
一般在网络请求结束后,在更新界面之前就把每个 cell 的高度算好,缓存到相对应的 model 中。

3、避免阻塞主线程。

很多时候我们需要从网络请求图片等,把这些操作放在后台执行,并且缓存起来。现在我们大都使用 SDWebImage 进行网络图片处理,正常的使用是没有大问题的,但是如果对性能要求比较高,或者要处理gif图,还是推荐 YYWebImage

4、按需加载。

这一条真的是看各位喜好了,我是觉得滚动的过程中有大量的 “留白” 并不太好,不过作为优化的建议还是要考虑的。
如快速滚动时,仅绘制目标位置的 cell ,可以提高滚动的顺畅程度。
具体可以参考 VVebo

5、减少SubViews的数量。

总觉得这条有点多余,能简单点的我们肯定不会做复杂了吧。这更多的取决于UI界面的复杂度。

6、尽可能重用开销比较大的对象。

NSDateFormatterNSCalendar等对象初始化非常慢,我们可以把它加入类的属性当中,或者创建单例来使用。

7、尽量减少计算的复杂度

在高分屏尽量用 ceil 或 floor 或 round 取整。不要出现 1.7,10.007这样的小数。

8、不要动态的add或者 remove子控件

最好在初始化时就添加完,然后通过hidden来控制是否显示。

异步绘制

//异步绘制
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
    });
});

YYText的使用
这个框架涉及到的方面还是很多的,在这里说再多的理论还是不如自己去看代码的好。
关于用法,没什么比YY作者说的更明白的了:

当获取到 API JSON 数据后,我会把每条 Cell 需要的数据都在后台线程计算并封装为一个布局对象 CellLayout。CellLayout 包含所有文本的 CoreText 排版结果、Cell 内部每个控件的高度、Cell 的整体高度。每个 CellLayout 的内存占用并不多,所以当生成后,可以全部缓存到内存,以供稍后使用。这样,TableView 在请求各个高度函数时,不会消耗任何多余计算量;当把 CellLayout 设置到 Cell 内部时,Cell 内部也不用再计算布局了。

UITableView的优化主要从三个方面入手:

  • 提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法;
  • 异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口;
  • 滑动时按需加载,这个在大量图片展示,网络加载的时候很管用!(SDWebImage已经实现异步加载,配合这条性能杠杠的)。

除了上面最主要的三个方面外,还有很多几乎大伙都很熟知的优化点:

  • 正确使用reuseIdentifier来重用Cells
  • 尽量使所有的view opaque,包括Cell自身
  • 尽量少用或不用透明图层
  • 如果Cell内现实的内容来自web,使用异步加载,缓存请求结果
  • 减少subviews的数量
  • heightForRowAtIndexPath:中尽量不使用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
  • 尽量少用addView给Cell动态添加View,可以初始化时就添加,然后通过hide来控制是否显示
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值