前言:
Cell重用创建不对就会直接崩溃,这的确令人头疼,总结一下Cell的重用问题,加深一下自己的印象,共勉!!!
Cell的重用机制:
无论是UITableView还是UICollectionView,都有许多需要显示的cell (item), 但是屏幕的大小是有限的,一次只能显示那么几个,如果我们把所有的数据全部都加载进去,暂时又看不到,就会非常浪费内存.
那么该如何避免这种不必要的内存消耗呢?就是每次只显示屏幕能放得下的cell的数据,在用户滑动屏幕的过程中,再去加载新的数据,于是就有了cell的重用机制,重用机制实现了数据和显示的分离,并不会为每个要显示的数据都创建一个Cell,一般情况下只创建屏幕可显示的最大的cell个数+1,每当有一个cell从屏幕消失,就将其放到缓存池中,如果有新的cell出现,就去缓存池中取,如果缓存池中没有,再创建。
Cell重用的创建:
1.注册Cell,那种注册都行
- (void)viewDidLoad {
[super viewDidLoad];
// 注册系统Cell
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
//class代码自定义Cell 第二个参数自己定义和缓存查找方法的identifier 必须对应
[self.tableView registerClass:[testTableViewCell class] forCellReuseIdentifier:@"haha"];
//xib 注册Cell,第二个参数必须和该xib中identifier对应
[self.tableView registerNib:[UINib nibWithNibName:@"testTableViewCell" bundle:nil] forCellReuseIdentifier:@"haha"];
}
- 从缓存池查找cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 重用队列中取单元格 由于上面已经注册过单元格,系统会帮我们做判断,不用再次手动判断单元格是否存在
testTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"haha" forIndexPath:indexPath];
return cell;
}
注册cell和该方法配套使用,还有一种创建不用注册Cell,但需要手动判断Cell是否为nil,为nil创建Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
cell.textLabel.text = @"手动判断缓存池是否有cell方法创建";
return cell;
}
UICollectionView重用的创建必须先注册,因为UICollectionView只有dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath 这个方法
- (void)viewDidLoad {
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
return cell;
}