2010-08-23 70 views
32

當蘋果爲第一款iPhone開發UITableView時,它們在滾動時遇到了性能問題。然後一位聰明的工程師發現,其原因是物體的分配帶有價格,所以他想出了一種重用單元的方法。UITableView dequeueReusableCellWithIdentifier理論

「對象分配有性能上的成本,尤其是如果分配有在短期內,比如說,當 用戶滾動表視圖。如果你重用的小區,而不是分配 新的,反覆發生的大大提升桌面表現。「

來源:iOS的參考庫

要重新使用單元格使用:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

現在,我想知道是,到底發生了什麼嗎?如果有一個具有該標識符的單元格並返回該單元格,它是否會查看TableView?好吧,是啊,但如果它發送一個引用而不是分配,我有一個表視圖,讓我們說4個單元格具有相同的標識符都是可見的。它怎樣才能將自身擴展爲四個實例而不分配?

我想知道這一點,因爲我正在構建日曆類型組件,並且所有單元格都具有相同的結構,只有更改中的文本。所以如果我能以某種方式重用我的單元而不是分配,我想我可能會獲得更好的性能。

我自己的理論是它分配了四個單元格(因爲它也有)。當一個單元從屏幕上消失時,它將被放入TableView重用隊列中。當需要一個新的單元時,它會查詢具有相同標識符的單元是否可用,它會在該單元上調用prepareForReuse方法,並將其自身從隊列中移除。

+0

簡答:是的。它有一個單獨的重用隊列/集合,與表中已有的不同。 – 2010-08-23 23:18:15

回答

43

dequeueReusableCellWithIdentifier:只返回cell如果它已被標記爲可以重新使用。這就是爲什麼幾乎所有的cellForRowAtIndexPath:方法,你會看到類似

 


UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (nil == cell) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:CellIdentifier]; 
} 

// Do something to cell 

return cell; 
 

實際上,足夠的行會被分配到填充的tableview(加一或兩個以上)的可見部分。由於屏幕上有cells scroll,因此將它們從table中刪除,並標記爲reuse。隨着「可用單元格」隊列的增長,請求dequeued cell的線路將開始獲取要使用的cell,此時您不必再分配。

+3

'一個或兩個以上'部分不正確。它恰好分配了*所需要的。試試這個,你會看到。 – 2010-08-23 23:18:51

+0

確實如St3fan所說,如果你NSLog的方法,它會要求一個細胞,你會看到它只會要求所需的細胞。 – Mark 2010-08-24 08:23:42

+2

我的解釋是,我可能有點匆忙。 「需要什麼」取決於環境。當你開始滾動UITableView時,更多因素起作用。舉一個例子:如果你非常快速地滾動一個長表視圖,當沒有任何可用於出列時,可能會導致表請求一個單元格。 – 2010-08-24 08:53:54

13

deqeueueReusableCellsWithIdentifier:代碼將是這個樣子:

- (UIView*) dequeueReusablePage 
{ 
    UIView* page = [reusablePages_ anyObject]; 
    if (page != nil) { 
     [[page retain] autorelease]; 
     [reusablePages_ removeObject: page]; 
    } 
    return page; 
} 

(從我自己的項目,我做的分頁滾動視圖的意見/頁類似的東西之一獲得)所以這用可重複使用的對象保持簡單的NSMutableSet

當單元格從屏幕上滾動出來並且不再可見時,它們被放入這個集合中。

所以你從一個空集合開始,只有當你有更多的數據要顯示然後在屏幕上可見時,集合纔會增長。

已使用的單元格從屏幕頂部滾動,放入設置中,然後拍攝出現在屏幕底部的單元格。

2

dequeueReusableCellWithIdentifier的用途是使用較少的內存。如果我們在tableView中使用100個單元格,則需要每次創建100個單元格。它會降低應用程序的功能並可能導致崩潰。 對於該dequeueReusableCellWithIdentifier初始化我們創建的特定數量的單元格,單元格將再次使用以進一步處理。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *TableIdentifier = @"YourCellIdentifier"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier]; 

    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifier]; 
    } 

    ExternalClassTableViewCell *myCell = [[ExternalClassTableViewCell alloc]init]; 
    myCell.MyCellText.text = [tableData objectAtIndex:indexPath.row]; 
    myCell.MyCellImage.backgroundColor = [UIColor blueColor]; 

    return cell; 
} 
相關問題