1、重用機制Cell是如何新建的?
很多人以爲Cell在新建的時候只新建一個,其他的都重複使用那一個,但事實上並不是這樣的,新建多少個Cell,並加入重用隊列是取決於初始化時屏幕中能容納多少個Cell,(5S模擬器測試)經測試Cell高44時,新建14個Cell。Cell高120時,count:6,新建6個Cell。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static int count = 0;
static NSString *celleIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:celleIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:celleIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
count ++;
}
if (indexPath.row < 10) {
cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
NSLog(@"count:%d,cellheight:%f",count,cell.frame.size.height);
return cell;
}
2、Cell重用時是如何取出來的?
在使用120高度的Cell時,重用隊列中將只有6個存儲的Cell,在下方代碼中到第6個Cell,即textLabel == 6時 已用開始使用重用隊列中的Cell,由打印的數據可知,init textLabel爲0,這使用的是第一個存入的隊列Cell,textLabel == 7時, init textLabel爲1,使用的是存入的第二個Cell,一直到使用第六個完成一輪後再重新使用第一個存入的Cell,由此可以推斷,Cell重用時是秉承先進先出的原則,循環使用。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static int count = 0;
static NSString *celleIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:celleIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:celleIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
count ++;
}
NSLog(@"init textLabel:%@",cell.textLabel.text);
if (indexPath.row < 10) {
cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
}
NSLog(@"count:%d,textLabel:%@",count,cell.textLabel.text);
return cell;
}
3、reuseIdentifier的作用?
在加載第11個Cell的時候開始,Cell的celleIdentifier換成了@"cell2",並且將第11個Cell的textLabel內容換乘@"this is 20",根據截圖可知,由於更換了celleIdentifier,在第11個Cell加載時是沒有init textLabel的,並且count開始自增直至12,說明使用新的celleIdentifier使tableview重新建了一個隊列並且放入了6個新的Cell,並且在6個一輪之後重用了,新隊列裏的Cell。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static int count = 0;
static NSString *celleIdentifier = @"Cell";
if (indexPath.row > 10) {
celleIdentifier = @"Cell2";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:celleIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:celleIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
count ++;
}
NSLog(@"init textLabel:%@",cell.textLabel.text);
if (indexPath.row < 10) {
cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
}else if (indexPath.row == 11){
cell.textLabel.text = @"this is 20";
}
NSLog(@"count:%d,textLabel:%@",count,cell.textLabel.text);
return cell;
}
4、爲什麼使用重用機制後我的數據亂掉了?
在解釋第三點時,在第11個Cell之後textLabel一直顯示的是null,這是因爲我沒有在重用後,對這個Cell進行操作,一般在使用重用後,都需要對Cell的數據進行處理。如果沒有處理的話,一種情況就像上面截圖一樣,由於重用隊列裏面的Cell的textLabel就是沒有值的,取出來之後還是不進行操作,即爲null。還有一種情況是打印出this is 20的這種情況,因爲重用隊列裏面的Celld的textLabel裏面有值,取出重用後不進行操作的話就會使用之前隊列裏Cell的textLabel這個值,所以後面有好幾個重用Cell2隊列中第一個存入的Cell時,打印出來的數據也爲this is 20。
總結:不同的reuseIdentifier代表了不同的隊列,重用時按隊列順序先進先出,一輪之後再重新從第一個開始重用。