tableView的简单认识
UITableView最核心的思想就是UITableViewCell的重用机制。简单的理解就是:重用机制实现了数据和显示的分离,并不为每个数据创建一个UITableViewCell,我们只创建屏幕可显示的最大的cell个数+1,然后去循环重复使用这些cell,既节省空间,又达到我们需要显示的效果.。这样做的好处可想而知,极大的减少了内存的开销,尽管这样但是我们在做项目的时候会发现有的时候滑动tableView还是会很卡顿
剖析
我们来看看UITableView的回调方法,其中有两个非常重要的回调
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
相信这个两个回调大家都不陌生,那下面我问大家个问题,这两个回调会先调用那个呢?理想上我们是会认为UITableView会先调用前者,再调用后者,因为这和我们创建控件的思路是一样的,先创建它,再设置它的布局。但实际上却并非如此,我们都知道,UITableView是继承自UIScrollView的,需要先确定它的contentSize及每个Cell的位置,然后才会把重用的Cell放置到对应的位置。我们知道了UITableView会先走
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
回调,我们可以在这里把我们需要展示的数据尺寸算出来,那么问题来了 怎么算。
怎么算
我们需要创建两个模型:
一个是数据模型
@interface TableViewModel : NSObject
/**正文文字*/
@property (nonatomic, strong) NSString *text;
/**图片链接*/
@property (nonatomic, strong) NSString *photo_URL;
/**图片数组*/
@property (nonatomic, strong) NSArray *photoArr_URL;
@end
一个Frame模型
@interface TableViewFrameModel : NSObject
@property (nonatomic, strong) TableViewModel *model;
/**正文的frame*/
@property (nonatomic, assign) CGRect contentF;
/**图片的frame*/
@property (nonatomic, assign) CGRect photosViewF;
/**cell的高度*/
@property (nonatomic, assign) CGFloat cellHeight;
@end
我们请求到数据之后,把数据模型给Frame模型让他帮我们把数据算出
NSArray *model = [TableViewModel mj_objectArrayWithKeyValuesArray:self.items];
for (TableViewModel *infomodel in model) {
TableViewFrameModel *frameModel = [[TableViewFrameModel alloc] init];
frameModel.model = infomodel;
[_infoFrameModel addObject:frameModel];
}
我们最终获得到一个Frame模型数组(_infoFrameModel),我们只需要
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
TableViewFrameModel *frame = self.infoFrameModel[indexPath.row];
return frame.cellHeight;
}
这样我们就可以先把每一行Cell的高度计算,然后去铺数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *ID = @"cell";
AdaptiveCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[AdaptiveCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];
}
cell.frameModel = self.infoFrameModel[indexPath.row];
return cell;
}
这样就大大的提高了UITableView的性能
总结
- 我们需要提前计算好每行Cell内的控件大小和每行Cell的高度
- 异步加载:比如我们加载图片可是使用(SDWebImage)也可以提高我们tableView的性能
- 创建控件尽量少使用addView在Cell添加控件,可以在开始的时候创建,通过hidden来设置显示和隐藏
- 尽量少使用或者不使用透明图层和圆角设置
本人新手呆鸟,忘各位老司机多多鞭策,使我快速成长。谢啦
网友评论