(一)、UITableView的执行顺序
-
numberOfSectionsInTableView(确定有几组) -> numberOfRowsInSection(确定每组有多少的行) -> heightForRowAtIndexPath(确定每行cell的高度)
-
以上信息确定完毕后再依次调用cellForRowAtIndexPath -> heightForRowAtIndexPath
-
当滚动获取超出屏幕的cell 会再依次调用 cellForRowAtIndexPath -> heightForRowAtIndexPath
#import "MyTableViewController.h"
@interface MyTableViewController ()
@end
@implementation MyTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// NSLog(@"viewDidLoad");
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// NSLog(@"viewWillAppear");
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// NSLog(@"viewDidAppear");
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"---------------------------------");
NSLog(@"numberOfSections");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"numberOfRows");
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"reuseIdentifier"];
}
cell.textLabel.text = [NSString stringWithFormat:@"我是第 %ld 行",(long)indexPath.row];
NSLog(@"cellForRowAtIndexPath");
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"heightForRowAtIndexPath");
return 100;
}
@end
打印结果:
2017-10-23 15:44:30.834 Test[79696:9847728] ---------------------------------
2017-10-23 15:44:30.834 Test[79696:9847728] numberOfSections
2017-10-23 15:44:30.835 Test[79696:9847728] numberOfRows
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.835 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.836 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.836 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.840 Test[79696:9847728] ---------------------------------
2017-10-23 15:44:30.842 Test[79696:9847728] cellForRowAtIndexPath
2017-10-23 15:44:30.842 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.845 Test[79696:9847728] cellForRowAtIndexPath
2017-10-23 15:44:30.845 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.846 Test[79696:9847728] cellForRowAtIndexPath
2017-10-23 15:44:30.846 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.846 Test[79696:9847728] cellForRowAtIndexPath
2017-10-23 15:44:30.846 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.847 Test[79696:9847728] cellForRowAtIndexPath
2017-10-23 15:44:30.847 Test[79696:9847728] heightForRowAtIndexPath
2017-10-23 15:44:30.849 Test[79696:9847728] ---------------------------------
2017-10-23 15:47:59.648 Test[79696:9847728] cellForRowAtIndexPath
2017-10-23 15:47:59.648 Test[79696:9847728] heightForRowAtIndexPath
UITableView的回调顺序是先多次调用tableView:heightForRowAtIndexPath:以确定contentSize及Cell的位置,然后才会调用tableView:cellForRowAtIndexPath:,从而来显示在当前屏幕的Cell。
举个例子来说:如果现在要显示100个Cell,当前屏幕显示5个。那么刷新(reload)UITableView时,UITableView会先调用100次tableView:heightForRowAtIndexPath:方法,然后调用5次tableView:cellForRowAtIndexPath:方法;滚动屏幕时,每当Cell滚入屏幕,都会调用一次tableView:heightForRowAtIndexPath:、tableView:cellForRowAtIndexPath:方法。
(二)、UITableView的流畅性优化
- 1、 提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法;
- 2、异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口;
- 3、滑动时按需加载,这个在大量图片展示,网络加载的时候很管用!(SDWebImage已经实现异步加载,配合这条性能杠杠的)。
除了上面最主要的三个方面外,还有很多几乎大伙都很熟知的优化点:
- 正确使用reuseIdentifier来重用Cells
- 尽量使所有的view opaque,包括Cell自身
- 尽量少用或不用透明图层
- 如果Cell内现实的内容来自web,使用异步加载,缓存请求结果
- 减少subviews的数量
- 在heightForRowAtIndexPath:中尽量不使用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
- 尽量少用addView给Cell动态添加View,可以初始化时就添加,然后通过hide来控制是否显示
网友评论