UITableView的cell複用,UICollectionView的cell複用
阿新 • • 發佈:2019-01-02
關於UITableView的Cell複用談談我的一些心得
UITableView是ios開發中使用率極高的一個控制元件,就我個人來說,幾乎我做的每一個View上都有她的身影。但是很長一段時間,我對她的理解都很膚淺。對我來說觸動較大的兩個東西,一個是前面提到的自定義UITableViewCell,再有就是今天要提的這個複用了。 所謂複用表面意思來理解就是重複利用了。大致的工作原理就是:UITableView屬於lazy loading,也就是隻載入會在介面上顯示的部分。舉個例子,比如說UITabeview的高度是460,咱們每個Cell的高度是230,這樣的話, 手機介面上最多就顯示兩個Cell,當你向上划動,第一個Cell一些離開介面,第三個Cell的一些出現在介面的時候會再建立第三個Cell。注意關鍵 部分到了,再第二個Cell開始離開介面,第四個Cell出現的時候,這時候不會建立第四個Cell,而是直接複用的第一個Cell!也就是說無論你的 UITableView裡有十條或者三十條資料,只會建立三個Cell來展示這些資料! 總的來說,這種工作機制很合理,無論從CPU和記憶體的角度考慮都很節省資源,但是這裡有一個問題就是:這種機制是用來展示結構一樣的資料的!很多時候我們 總要實現動態載入,總要有一個Cell,與其它的Cell不同,用來顯示“正在載入中”或者“載入更多”之類的東西。這時候在Cell複用的機制下會出現 重疊的現像! ok,光說不練,沒啥用,簡單演示一下:
_objects = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
[_objects addObject:[NSString stringWithFormat:@"text %d",i]];
}
[_objects addObject:@"載入更多"];
for (int i = 0; i < 10; i++) {
[_objects addObject:[NSString stringWithFormat:@"text %d",i]];
}
我們在一個數組裡加了21條資料,而且中間那條不一樣,屬於我們說的資料結構不一致的那種。 cell展示部分我們是這麼寫的:
NSString *_text = [_objects objectAtIndex:indexPath.row];
//我們希望“載入更多”這行是居中顯示
if (![_text hasPrefix:@"text"]) {
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
cell.textLabel.text = _text;
ok,我們執行一下:
向下拖動一下,目前看來是沒有問題的。可是當我們上下拖動了幾次以後,問題出現了。。
由於cell的複用機制,“文字居中”(UITextAlignmentCenter)這種屬性漸漸的被其它Cell用上了。這個腫麼辦呢?最早的時候,我通過了網上搜索,大家都說這是Cell的複用的問題。而我想當然的認為,既然是複用,那我就不復用就好了。於是我把
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
改成了:
if (cell != nil) {
[cell release];
}
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
是的,在我這麼改完以後,UITableView看起來確實是按我想的方式工作了,事實上很長的時間裡都沒再出過錯。(不要問我為什麼不在if後面 跟個else把文字的屬性設成“文字居左”(UITextAlignmentLeft),因為實際的資料比這複雜的多。)這種方法一直工作的很ok(確切 的說是在iphone4上),直到很久以後,我把同樣的程式在itouch上一跑,沒載入多少條資料就提示Received memory warning了。。。。。 所以我知道了正確的Cell複用的方式:
NSString *_text = [_objects objectAtIndex:indexPath.row];
UITableViewCell *cell;
if ([_text hasPrefix:@"text"]) {
static NSString *CellIdentifier = @"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
else {
static NSString *CellIdentifier = @"CellReuse";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
cell.textLabel.text = _text;
UITableView是ios開發中使用率極高的一個控制元件,就我個人來說,幾乎我做的每一個View上都有她的身影。但是很長一段時間,我對她的理解都很膚淺。對我來說觸動較大的兩個東西,一個是前面提到的自定義UITableViewCell,再有就是今天要提的這個複用了。 所謂複用表面意思來理解就是重複利用了。大致的工作原理就是:UITableView屬於lazy loading,也就是隻載入會在介面上顯示的部分。舉個例子,比如說UITabeview的高度是460,咱們每個Cell的高度是230,這樣的話, 手機介面上最多就顯示兩個Cell,當你向上划動,第一個Cell一些離開介面,第三個Cell的一些出現在介面的時候會再建立第三個Cell。注意關鍵 部分到了,再第二個Cell開始離開介面,第四個Cell出現的時候,這時候不會建立第四個Cell,而是直接複用的第一個Cell!也就是說無論你的 UITableView裡有十條或者三十條資料,只會建立三個Cell來展示這些資料! 總的來說,這種工作機制很合理,無論從CPU和記憶體的角度考慮都很節省資源,但是這裡有一個問題就是:這種機制是用來展示結構一樣的資料的!很多時候我們 總要實現動態載入,總要有一個Cell,與其它的Cell不同,用來顯示“正在載入中”或者“載入更多”之類的東西。這時候在Cell複用的機制下會出現 重疊的現像! ok,光說不練,沒啥用,簡單演示一下:
_objects = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
[_objects addObject:[NSString stringWithFormat:@"text %d",i]];
}
[_objects addObject:@"載入更多"];
for (int i = 0; i < 10; i++) {
[_objects addObject:[NSString stringWithFormat:@"text %d",i]];
}
我們在一個數組裡加了21條資料,而且中間那條不一樣,屬於我們說的資料結構不一致的那種。 cell展示部分我們是這麼寫的:
NSString *_text = [_objects objectAtIndex:indexPath.row];
//我們希望“載入更多”這行是居中顯示
if (![_text hasPrefix:@"text"]) {
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
cell.textLabel.text = _text;
ok,我們執行一下:
向下拖動一下,目前看來是沒有問題的。可是當我們上下拖動了幾次以後,問題出現了。。
由於cell的複用機制,“文字居中”(UITextAlignmentCenter)這種屬性漸漸的被其它Cell用上了。這個腫麼辦呢?最早的時候,我通過了網上搜索,大家都說這是Cell的複用的問題。而我想當然的認為,既然是複用,那我就不復用就好了。於是我把
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
改成了:
if (cell != nil) {
[cell release];
}
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
是的,在我這麼改完以後,UITableView看起來確實是按我想的方式工作了,事實上很長的時間裡都沒再出過錯。(不要問我為什麼不在if後面 跟個else把文字的屬性設成“文字居左”(UITextAlignmentLeft),因為實際的資料比這複雜的多。)這種方法一直工作的很ok(確切 的說是在iphone4上),直到很久以後,我把同樣的程式在itouch上一跑,沒載入多少條資料就提示Received memory warning了。。。。。 所以我知道了正確的Cell複用的方式:
NSString *_text = [_objects objectAtIndex:indexPath.row];
UITableViewCell *cell;
if ([_text hasPrefix:@"text"]) {
static NSString *CellIdentifier = @"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
else {
static NSString *CellIdentifier = @"CellReuse";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
cell.textLabel.text = _text;