相信很多人多下面這段代碼都非常的熟悉。
在使用TableView的時候,下面一段代碼是必須的,也是最標準的,也是最核心的:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CMainCell = @"CMainCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CMainCell]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease]; } //自訂cell的內容 cell.textlabel.text = @"XXX"; return cell; }
可以這樣理解這段代碼。
uitableviewcellll有一個隊列用來專門存放那些產生過的,但是後來由於滾動tableView而隱藏起來的cell,
比如一個table有20個cell,
但是螢幕只能顯示5個,(當然iPhone5可能會顯示6個),那麼就會有其他的cell沒有顯示出來,
但是在滑動tableview的時候便會顯現。
而代碼中:
static NSString *CMainCell = @"CMainCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CMainCell];
就是從隊列中根據標示符取出一個暫時不用的cell,只有cell為nil,也就是隊列中沒有舊的cell的時候,
才會執行:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease];
以此產生一個新的cell。
如果有舊的,就不用執行這個語句了,這樣節省資源,算作一種重用。
在tableView初始化的時候隊列中肯定沒有cell的,所以每個cell產生的時候都會執行一遍這個代碼:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease];
當螢幕顯示滿了,向上滾動顯示下一行時,就會把第一行隱藏,放到那個隊列中,
然後新增加的一行執行語句:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CMainCell];
的時候,結果就不是nil了,然後,就跳過語句2了,這樣就節約資源了。
當然,上面這樣對於使用系統提供的cell格式(左中右的結構)是沒有什麼問題,
但是如果自己在cell上添加一些控制項時(自訂cell的tableview),
比如添加一個label和button的時候,有時就會出現問題。注意,是有時。
比如,在各個cell的label的文字不相同時。
首先這個添加的過程一定要在語句:
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease];
}
之後,這樣才是一次添加,
如果放在語句:
cell.textlabel.text = @"XXX";
之後,那麼由於cell的重用可能舊的上面已經有label了,你再添加一個,造成多次添加。
其次label的文本值必須保證每次都要重新設定,也就是在語句:
cell.textlabel.text = @"XXX";
之後設定,這樣才能保證每次必須執行。
如果放在語句:
後面,那麼當使用舊的cell時,仍會保留舊的label文字,這是不對的。
所以是在:
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease];
}
後添加,在:
cell.textlabel.text = @"XXX";
後設定,可以在添加的時候設一個tag值,這樣可以在後面處通過tag值擷取控制項設定。
關於語句:
static NSString *CMainCell = @"CMainCell";
如果每個cell的結構完全相同,那沒問題,就用這一個標識符,
但是如果各個cell結構不完全相同,有的有textfield,有的有button,有的有switch,
那就不能互相重用了,只能每行用不同的標識符了,
可以方便的利用(@"CMainCell%d", indexPath.row),保證不會重複,
多組的再加上組號。
那這還有必要用cell的重複利用嗎?
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CMainCell];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease];
}
還是需要的。
因為當自己滾動隱藏,下次再顯示出來的時候,還是可以重用的。
標識符完全可以每次用一個新的,但為了最大限度的重用性,節省資源,才想了這麼多辦法。
巧妙地利用tag可以讓你的cell無懈可擊。