使用可重用 cell 的两种方式
1. 最常用的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if ( !cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } return cell; }
2. 注册使用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; return cell; }
使用这种方法需要在创建 tableView 的时候注册
//下面这句代码的作用就是告诉 tableView ,它上面的 cell 都是根据 UITableViewCell 类型创建的 //如果重用的 cell 找不到,系统会自己根据这个类型创建一个 cell ,不需要编程人员创建; [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
如果不先注册,程序在运行时会 crash
unable to dequeue a cell with identifier cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard
不能出队一个标识为cell 的单元格,必须为这个标识符注册一个 nib 或者一个类或者连接一个在 storyboard 里的原型单元格
在我看来使用第一种方式更为灵活方便
1)第二种方法是在 iOS 6 及以后才开始支持的,对于早期的版本并不支持,应用到真机上,兼容性就是一大问题;
2)第二种方法虽然代码更加精简了,但是如果需要使用自定义的 cell,即只改变 cell 上的 textLabel 已经不能满足要求的时候,开发者需要根据自己的需要来添加不同的 view ,这时候,因为不能够定位到哪些 cell 是重用的,哪些不是,添加获得一个 cell 都需要添加 view ,这样,当滑动手机屏幕的时候,在那些重用的 cell 上就再次添加了一个相同的 view,随着滑动次数的增多,一个 cell 上叠加的 view 也越多,造成大量的内存消耗,这与 cell 重用的思想背道而驰;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image"]]; imageView.frame = CGRectMake(15, 2, 40, 40); [cell addSubview:imageView]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(65, 2, 100, 20)]; label.text = @"Hello"; [cell addSubview:label]; UILabel *subLabel = [[UILabel alloc] initWithFrame:CGRectMake(65, 22, 100, 20)]; subLabel.text = @"你好"; [cell addSubview:subLabel]; return cell; } //运行上面的代码,并不断滑动屏幕,会发现 cell 上的字体会变粗变黑,这个就是因为叠加了很多的 label 的原因;图片也叠加了很多,知识效果上看不明显,在去观察内存,会发现内存占用会越来越大
3)第二种方法使用之前必须先有 tableView 注册才能使用,否则程序崩溃,但在开发过程中很容易忘记, 而且使用这种方法不能设定 cell 的显示样式
使用第一种方法的时候,如果是想向 cell 上添加 view , 相同的部分在 if 语句里完成,这样就不会在同一个 cell 上叠加很多相同的 view 了
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if ( !cell ) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"]; //可以设定 cell 的显示样式为 subTitle UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image"]]; imageView.frame = CGRectMake(15, 2, 40, 40); [cell addSubview:imageView]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(65, 2, 100, 20)]; label.text = @"Hello"; [cell addSubview:label]; UILabel *subLabel = [[UILabel alloc] initWithFrame:CGRectMake(65, 22, 100, 20)]; subLabel.text = @"你好"; [cell addSubview:subLabel]; } return cell; }