UITableView和UICollectionView的Cell重用问题

前言:
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"]; }

  1. 从缓存池查找cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //重用队列中取单元格 由于上面已经注册过单元格,系统会帮我们做判断,不用再次手动判断单元格是否存在 testTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"haha" forIndexPath:indexPath]; return cell; }

【UITableView和UICollectionView的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; }

    推荐阅读