##问题 在TableView中,我们经常需要加载非常非常多的Cell,每个Cell都有独立的内容。这时,如何才能保证你的TableView不会因加载过多Cell而挂掉呢?
Apple给出的解决办法是重用Cell。
##Cell的加载与重用 TableView中维护着一个cell重用队列。当TableView第一次加载时,重用队列是空的。同时,TableView调用-(UITableViewCell *)tableView: cellForRowAtIndexPath:
,用于加载屏幕可视区域中的Cell(注意噢!只加载可是区域的Cell)。iPhone可视区域有限,一般只能容纳15个左右的Cell。
当滚动TableView时,部分Cell会脱离可视区域。这些脱离了可视区域的Cell并不会被delloc销毁,而是放到重用队列中。
在滚动的同时,另一些新的Cell会进入可视区域。此时由于重用队列中存在可重用的Cell,因此TableView并不会alloc创建新的Cell,而是从重用队列中取出Cell,并给text,image等附上新的值,以供那些新进入可视区域的Cell使用。
开启重用机制
开启重用机制有两种方式:
1. 远古的手工办法(可用但不推荐)
这种做法的思路是: 每次TableView在请求需要一个可重用的Cell时,手工进行一次非空判断,如果存在可重用的Cell,则使用它,否则就alloc创建一个新的Cell。
static NSString *CellIdentifier = @"CellIdentifier";
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:SimpleTableIdentifier];
}
cell.textLabel.text = @"new text";
return cell;
}
2. 使用注册机制开启重用机制
注册机制会对一种类型的Cell进行注册,注册的结果是:
- 当TableView需要从重用队列中获取Cell,但重用队列为空时,则自动alloc创建新的Cell。
- 当TableView需要从重用队列中获取Cell,且重用队列中有可重用的Cell时,TableView优先使用可重用的Cell,而不是创建新的Cell。
我们需要根据创建Cell的方式,选择正确的方法对cell进行注册和重用。下面讲到的三种创建cell的方式可参考自定义Cell的三种方式
####A. 使用纯代码创建cell 直接在代码中对cell注册。
//现在ViewDidload中注册
static NSString *CellIdentifier = @"CellIdentifier";
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[MyCell class] forCellReuseIdentifier: CellIdentifier];
//然后就不用判断可重用Cell是否为nil了
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *myCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
myCell = @"new text";
return myCell;
}
####B. 使用storyboard + 代码的方式 只需在storyboard中设置Cell的Identifier即可。需要注意的是,如果在使用了自定义cell,千万不要同时在storyboard和代码中对cell进行注册,这会造成cell渲染失败,一片空白。
####C. 使用xib + 代码 xib方式的cell只需在代码中注册即可。
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = @[@"1", @"2", @"3"];
UINib *nib = [UINib nibWithNibName:@"CellXib" bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSString *str = [self.dataSource objectAtIndex:indexPath.row];
[cell setTheValue:str];
return cell;
}
##Reference http://www.douban.com/note/232238166/