2013-05-05 157 views
19

我在我的UITableView中使用自定義UITableViewCell,但問題是,調用dequeueReusableCellWithIdentifier時,單元格永遠不會爲零。爲什麼是這樣 ?dequeueReusableCellWithIdentifier永遠不會返回零

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UINib *nib = [UINib nibWithNibName:@"PHResultTableViewCell" bundle: nil]; 
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"MyCell"]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath 
{ 
    PHResultTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"]; 
    if (cell == nil) 
    { 
     PackageHolidayItem *obj=[[PackageHolidayItem alloc]init]; 
     obj= [totalArray objectAtIndex:indexPath.row]; 
     cell.packageHolidayItem = obj; 
     [cell loadRow]; 

    } 
    return cell; 
}  
+1

您使用的故事板? – 2013-05-05 06:51:22

+0

即使你沒有註冊一個筆尖,並且dequeueReusableCellWithIdentifier可能返回nil,只在'if(cell == nil){...}'情況下配置該單元格是錯誤的。 – 2013-05-05 08:40:16

回答

0

我不相信它應該返回零。你爲什麼要這樣做?

方法dequeueReusableCellWithIdentifier返回一個即將顯示的單元格,所以實際上它不是空的 - 這樣就可以根據需要修改它。

14

它不會返回nil,因爲您已經註冊了一個用於單元重用的筆尖([[self tableView] registerNib:nib forCellReuseIdentifier:@"MyCell"];)。

如果dequeueReusableCellWithIdentifier:無法在tableviews reuse隊列中找到一個單元格,它將從您指定的nib中實例化一個新的單元格。

+0

也許,但他實際上在'viewDidLoad'中註冊了筆尖,並且註冊的筆尖優先於原型單元格。筆尖不能爲零,否則他會覆蓋單元原型,並且出列不會返回單元格。我想內部原型單元存儲的方式與註冊的筆尖相同。總而言之,對'registerNib:forCellReuseIdentifier:'的實際調用會導致出隊返回一個單元格,但也可能有一個原型單元格。唯一的辦法就是去掉'registerNib ::'調用。沒有冒犯,我完成了挑剔:-) – 2013-05-06 07:05:28

+0

雖然我欣賞詳盡的迴應,但當我瞥了一眼原始代碼示例時,我完全沒有注意到他註冊了NIB(這很有趣,因爲我清理了他的源代碼)。我只是對他有關'出列......'返回'nil'的問題作出迴應。正如我們所知,當您註冊NIB以及使用單元格原型時,都會發生這種情況。但是你說的很對,因爲他在他的代碼示例中註冊了一個NIB,導致'出列......'永遠不會返回'nil'。 – Rob 2013-05-06 23:00:23

2

正如其他人已經指出,如果你已經註冊了一個筆尖重用tableViewCell,你保證會得到一個單元格的實例。如果你想爲單元格設置一些值。你可以嘗試修改這樣

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 

     PHResultTableViewCell *cell = (PHResultTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"MyCell" 
                           forIndexPath:indexPath];]; 

     cell.packageHolidayItem = totalArray[indexPath.row];; 
     [cell loadRow]; 

     return cell; 
    }  
+0

是的,我正在使用故事板 – 2013-05-05 15:04:03

+0

@TrineHaalsMadsen請確認故事板中給出的cellIdentifier是否正確。我已經更新了我的答案。 – Anupdas 2013-05-05 15:37:20

22

你的代碼中的iOS 5開始,當你用故事板和您的重用標識符的原型故事板比賽,你不會得到一個零,從dequeueReusableCellWithIdentifier返回。

從蘋果文檔:

表視圖編程指南適用於iOS

創建和配置表視圖

用數據填充

如果動態表視圖dequeueReusableCellWithIdentifier:方法要求單元格在故事板中定義的,該方法始終返回有效的 單元格。如果沒有等待重複使用的再循環單元格,方法 會使用故事板本身中的信息創建一個新單元格。這個 消除了檢查零的返回值並手動創建一個 單元的需要。

您可以登錄單元格地址,以證明你的自我,他們被重用。但不要隨記錄一起出貨,它會真的讓你的桌子變慢。

NSLog(@"Deque Cell %p", cell); 

更好的是使用斷點來記錄它。

enter image description here

$25 = 0x097f9850 <DDSImageSubtitleCheckedTableViewCell: 0x97f9850; baseClass = UITableViewCell; frame = (0 22; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0x97f9740>> 
$26 = 0x0a6a4a00 <DDSImageSubtitleCheckedTableViewCell: 0xa6a4a00; baseClass = UITableViewCell; frame = (0 66; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0xa6a4b50>> 
$27 = 0x0a3ad250 <DDSImageSubtitleCheckedTableViewCell: 0xa3ad250; baseClass = UITableViewCell; frame = (0 110; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0xa3ad390>> 
$28 = 0x0a3ae640 <DDSImageSubtitleCheckedTableViewCell: 0xa3ae640; baseClass = UITableViewCell; frame = (0 176; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0xa3ae780>> 
$29 = 0x0972a370 <DDSImageSubtitleCheckedTableViewCell: 0x972a370; baseClass = UITableViewCell; frame = (0 220; 320 44); hidden = YES; autoresize = W; layer = <CALayer: 0x972a340>> 

如果你只是想地址

enter image description here

0x097f9850 
0x0a6a4a00 
0x0a3ad250 
0x0a3ae640 
0x0972a370 
+0

這兩個斷點設置屏幕截圖看起來是相同的,但得到不同的輸出。他們是否應該在「調試器命令」字段中有不同的內容? – pix 2013-10-08 06:03:46

+0

@pix好眼睛。感謝您輸入錯字,它應該是'p cell'而不是'po cell'p是原始打印,其中po是打印對象並調用[cell description]。我已經黑了圖像。再次感謝。 – GayleDDS 2013-10-08 16:41:54

+0

一個很好的破解!幾乎看起來好像你redid的截圖 – 2016-03-20 16:19:24

相關問題