tableview的优化问题

1. 使⽤用不透明视图。 不透明的视图可以极⼤大地提⾼高渲染 的速度。因此如⾮非必要,可以将 table cell及其⼦子视图的opaque 属性设为YES(默认值) 其中的特例包括背景⾊色,它的 alpha值应该为1(例如不要使⽤用 clearColor);图像的alpha值也 应该为1,或者在画图时设为不透 明。

2. 不要重复创建不必要的table cell

前⾯面说了,UITableView只需要⼀一 屏幕的UITableViewCell对象即 可。因此在cell不可⻅见时,可以将 其缓存起来,⽽而在需要时继续使⽤用 它即可。 ⽽而UITableView也提供了这种机 ,只需要简单地设置⼀一个 identifier即可:值得⼀一提的是,cell被重⽤用时, 内部绘制的内容并不会被⾃自动清 ,因此你可能需要调⽤用 setNeedsDisplayInRect: setNeedsDisplay⽅方法。 此外,在添加table cell的时候, 如果不需要动画效果,最好不要使

3. 减少视图的数⺫⽬目。 UITableViewCell包含了 textLabeldetailTextLabel imageViewview,⽽而你还可以 ⾃自定义⼀一些视图放在它的 contentView⾥里。然⽽而view是很 ⼤大的对象,创建它会消耗较多资 ,并且也影响渲染的性能。 如果你的table cell包含图⽚片, 数⺫⽬目较多,使⽤用默认的 UITableViewCell会⾮非常影响性 能。奇怪的是,使⽤用⾃自定义的 view,⽽而⾮非预定义的view,明显 会快些。 当然,最佳的解决办法还是继承 UITableViewCell,并在其drawRect:中⾃自⾏行绘制,

不要做多余的绘制⼯工作。 在实现drawRect:的时候,它的 rect参数就是需要绘制的区域, 个区域之外的不需要进⾏行绘制。 例如上例中,就可以⽤用

CGRectIntersectsRect CGRectIntersection CGRectContainsRect判断是否 需要绘制imagetext,然后再调 ⽤用绘制⽅方法。此外还可以创建CALayer,将内容 绘制到layer,然后对cell contentView.layer调⽤用 addSublayer:⽅方法。这个例⼦子 ,layer并不会显著影响性能, 但如果layer透明,或者有圆⾓角、 变形等效果,就会影响到绘制速度 了。解决办法可参⻅见后⾯面的预渲染 图像。

4.你会发现即使做到了上述⼏几点, 新的图像出现时,仍然会有短暂的 停顿现象。解决的办法就是在 bitmap context⾥里先将其画⼀一 ,导出成UIImage对象,然后 再绘制到屏幕,

5.不要阻塞主线程。 做到前⼏几点后,你的table view 动时应该⾜足够流畅了,不过你仍可 能让⽤用户感到不爽。常⻅见的现象就 是在更新数据时,整个界⾯面卡住不 ,完全不响应⽤用户请求。 出现这种现象的原因就是主线程执 ⾏行了耗时很⻓长的函数或⽅方法,在其 执⾏行完毕前,⽆无法绘制屏幕和响应 ⽤用户请求。其中最常⻅见的就是⺴⽹网络 请求了,它通常都需要花费数秒的 时间,⽽而你不应该让⽤用户等待那么 久。 解决办法就是使⽤用多线程,让⼦子线 程去执⾏行这些函数或⽅方法。这⾥里⾯面 还有⼀一个学问,当下载线程数超过 2,会显著影响主线程的性能。 因此在使⽤用ASIHTTPRequest ,可以⽤用⼀一个 NSOperationQueue来维护下载 请求,并将其 maxConcurrentOperation


1.cell进行复用

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


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

比如:

static NSString *CellIdentifier = @"LazyTableCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


很常规的,防止cell对象无限的被创建,等同于android里面适配器的方法

public View getView(int position, View convertView, ViewGroup arg2)


以上举例代码是可以让cell被重复使用,一般大概只会在可见页面部分的几个cell会被new下,其他的全部重复使用前面已经有的cell对象,到时候只要填充数据就可以了



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

那么在cell里面异步加载图片是个程序员都会想到,但是如果你给每个循环对象都加上异步加载,并且下滑的时候,这一操作将会被执行,虽然是异步,但是一个app里面的线程过多也会卡顿的,特别是在下滑操作的时候给每个图片进行异步加载




那么这里可以利用UIScrollViewDelegate代理很好的解决这问题

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

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

可以识别tableview禁止或者减速滑动结束的时候进行异步加载图片


以下方法来执行异步加载操作

//获取可见部分的对象

NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];

for (NSIndexPath *indexPath in visiblePaths)

{

    //获取的dataSource里面的对象,并且判断加载完成的不需要再次异步加载

    <code>

}



同时在cell绘制中也做限制

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


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

{

    //开始异步加载图片

    <code>

}


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


3.内存紧张的时候把开的线程都关了

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

- (void)didReceiveMemoryWarning{

    //  释放调异步加载图片的线程以及所有图片资源对象

    <code>

}

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

至此性能优化结束,来源于官方文案


//自己的话

1.先把cell的高度计算好再直接赋值,不用计算就快多了


2.不用系统的cell自己在异步线里面绘制cell


3.按需要加载,滚动很快的时候只加载目标范围内的cell


//三个方面

1.提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法;

2.异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口;

3.滑动时按需加载,这个在大量图片展示,网络加载的时候很管用!(SDWebImage已经实现异步加载,配合这条性能杠杠的)。

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


//其他方面

正确使用reuseIdentifier来重用Cells

尽量使所有的view opaque,包括Cell自身

尽量少用或不用透明图层

如果Cell内现实的内容来自web,使用异步加载,缓存请求结果

减少subviews的数量

heightForRowAtIndexPath:中尽量不使用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果

尽量少用addViewCell动态添加View,可以初始化时就添加,然后通过hide来控制是否显示





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值