UITableView滑动卡顿优化

废话

实际上,目前市面上iPhone设备(iPhone5s以上)都很少出现卡顿现象了,但是一些老设备的用户,特别还有一小部分iPhone4用户(iPhone4无法升级iOS8),给适配增加了难度。作为对自己严格要求的程序猿来说,app性能优化不仅仅局限于使用起来没问题,更在于APP耗电少,流畅,产品UI友好等,同时也给优化提出了新的要求。

UITableView滑动卡顿产生原因

无论是语音,视频,还是图片,实际上在UITableView上的显示都只是视图(通常是UIImageView视图)。加载的图片是视频里的一帧,或语言长度所对应的图片,或是图片的缩略图。目前市面上比较流行的应用,如今日头条,采用gif,推到底部就加载。
UITableview 的图文混排视图显示中的图片视图显示,由于加载需要时间在滑动过程中如果没有异步处理容易照成卡顿。

处理办法

1重用机制

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

这个代理方法的实现,在可见的页面是会重复绘制页面的,所以绝大部分人都会在这里做一些代码处理
比如:

static NSString *CellIdentifier = @"LazyTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

2异步加载图片

在cell里面异步加载图片是个程序员都会想到,但是如果你给每个循环对象都加上异步加载,并且下滑的时候,这一操作将会被执行,虽然是异步,但是一个app里面的线程过多也会卡顿的,特别是在下滑操作的时候给每个图片进行异步加载,所以只需要对当前需要显示的图片进行异步加载就可以了。
由于UITableView是UIScrollView的子类,实现UIScrollViewDelegate代理可以很好的解决这问题

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

在tableview停止或者减速滑动结束的时候进行异步加载图片。
以下方法来执行异步加载操作,

 //获取可见部分的对象
 NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
 for (NSIndexPath *indexPath in visiblePaths)
 {
         //获取的dataSource里面的对象,并且判断加载完成的不需要再次异步加载
          
 }

同时在cell绘制中也做限制,如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"LazyTableCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
         if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
            {
               //开始异步加载图片
                
            }
            return cell;
    }

在tableview 停止滑动的时候开始异步加载图片。

最后,也别忘记在内存紧张的情况下释放调所有的异步线程,以保证的你的app不会被系统强制关闭

- (void)didReceiveMemoryWarning{
//  释放调异步加载图片的线程以及所有图片资源对象

}

还有千万别忘记销毁的时候手动把所有的使用到的代理设置nil。

你可能感兴趣的:(iOS开发笔记,综合)