2010-06-07 58 views
1

我對UITableView單元渲染的正確行爲感到非常困惑。這裏的情況:所有的UITableCells一次渲染......爲什麼?

我有一個250個項目加載到表視圖,每個圖像的列表。爲了優化圖片下載,我遵循Apple的LazyTableImages示例代碼...幾乎完全遵循它。真正優秀的系統...作參考,這裏的蘋果示例代碼中的單元格渲染器:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // customize the appearance of table view cells 
    // 
    static NSString *CellIdentifier = @"LazyTableCell"; 
    static NSString *PlaceholderCellIdentifier = @"PlaceholderCell"; 

    // add a placeholder cell while waiting on table data 
    int nodeCount = [self.entries count]; 

    if (nodeCount == 0 && indexPath.row == 0) 
    { 
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier]; 
     if (cell == nil) 
     { 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
              reuseIdentifier:PlaceholderCellIdentifier] autorelease]; 
      cell.detailTextLabel.textAlignment = UITextAlignmentCenter; 
      cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     } 

     cell.detailTextLabel.text = @"Loading…"; 

     return cell; 
    } 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
             reuseIdentifier:CellIdentifier] autorelease]; 
     cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 

    // Leave cells empty if there's no data yet 
    if (nodeCount > 0) 
    { 
     // Set up the cell... 
     AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row]; 

     cell.textLabel.text = appRecord.appName; 
     cell.detailTextLabel.text = appRecord.artist; 

     // Only load cached images; defer new downloads until scrolling ends 
     if (!appRecord.appIcon) 
     { 
      if (self.tableView.dragging == NO && self.tableView.decelerating == NO) 
      { 
       [self startIconDownload:appRecord forIndexPath:indexPath]; 
      } 
      // if a download is deferred or in progress, return a placeholder image 
      cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"];     
     } 
     else 
     { 
      cell.imageView.image = appRecord.appIcon; 
     } 

    } 

    return cell; 
} 

所以 - 我實現蘋果的LazyTableImages系統有一個重要的缺陷:它開始於立即將所有圖像的所有下載。現在,如果我刪除此行:

//[self startIconDownload:appRecord forIndexPath:indexPath]; 

然後系統的行爲完全像你所期望的:新的圖像加載它們的佔位符滾動到視圖。但是,初始視圖單元格不會在單元格渲染器中沒有提示的情況下自動加載它們的圖像。所以,我遇到了一個問題:使用單元格渲染器中的提示,所有圖像立即加載。沒有提示,初始視圖不會加載。現在,這在Apple示例代碼中運行良好,這讓我想知道我的情況。這幾乎就像在前面建立所有的單元格,而不是顯示在顯示器中的8個左右。所以,我開始研究它,事實的確如此......我的桌子正在建造250個獨特的細胞!我不認爲UITableView是這樣工作的,我想我認爲它只構建了填充表格所需的項目。這是事實嗎?還是說它會在前面建立所有250個單元?我試圖將我的實現與Apple LazyTableImages示例進行比較,但發現NSLog似乎在Apple示例代碼中被禁用(這使得直接行爲比較非常困難)。這只是一個簡單的發佈設置,或者蘋果以某種方式鎖定了他們的示例,以便在運行時不能記錄輸出?

謝謝!

回答

1

哦,我的... mustISignUp在說「你肯定有更深層的根本問題」是絕對正確的。我有可變高度的表格行,我正在做所有高度計算和數據存儲在行本身上,而不是在填充它們的數據模型上。因此,所有單元格都是通過我的heightForRowAtIndexPath方法創建和填充的,該方法從單元格對象讀取單元格高度。所以 - 吸取了教訓。

感謝mustISignUp,我愛你的用戶名。

+1

嘿嘿,很高興你把它排序。 – hooleyhoop 2010-06-07 19:06:20

0

NSLog在Apple示例代碼中絕對沒有禁用。我不知道你爲什麼看不到它,但你肯定有一個更深層次的問題。

反正你比較: - 如果你有在屏幕上-tableView 6行:的cellForRowAtIndexPath:與指數稱爲6倍[0,0] - [0,5]。

那麼,你看到了什麼?調用-cellForRowAtIndexPath多少次?

1

你當然不應該有一個實際的UITableViewCell實例表中的每一行。您應該只能看到比UI中可見更多的實例。這是你的問題所在。它與加載圖像沒有任何關係。

我唯一一次看到大量單元實例化時,出隊的單元格是編碼器改變了tableview的框架,使其比屏幕大得多。桌面視圖保留足夠的單元格,使其不必看到任何可見內容就可以將其排出到自己的框架中。如果幀很大,那麼你會得到很多隊列中的單元。

NSLog可以在蘋果的例子中工作,所以如果你不能得到NSLog輸出,你會發現開發工具本身有些奇怪的事情發生。

您可能想關閉Xcode和模擬器,然後重新啓動,看看是否清除了奇怪的行爲。

相關問題