2010-10-09 67 views
4

我正在研究Feed閱讀器iOS項目。以反向時間順序在UITableView中列出供稿條目。啓動時,它們從數據庫加載到數組中。在同步上更新UITableView的模式?

當應用程序與提要同步時,它會爲新的順序創建一個新數組,然後更新表,將新數組與舊數組進行比較以確定要刪除,更新或插入的單元格。我做這件事的方式是天真的,因此非常低效:大量調用indexOfObject:來查看一個數組中的項是否在另一個數組中。兩次。對於每個新條目添加一次,以查看它是否在舊數組中,然後針對舊數組中的每個條目添加一次,以查看新數組中是否爲而不是

作爲一名數據庫專業人員,此設計冒犯了我。

但它必須是一個很常見的模式。什麼纔是最合適的,充分的可可方法呢?

回答

4

原來我是在這個錯誤。我發現的解決方案是照常添加和刪除陣列中的項目,然後根據需要爲每個添加,更改或移動的行調用insertRowsAtIndexPaths:withRowAnimation:reloadRowsAtIndexPaths:withRowAnimation:deleteRowsAtIndexPaths:withRowAnimation:。我以前的計劃中的錯誤是我應該等到所有的改變和完成,然後在beginUpdates/endUpdates區塊中只調用一次這些方法。原來這個塊實際上並不是必須的,因爲修改方法可以在它們之外調用。

對於插入,更新或刪除的每個單元格調用每個方法一次要比計算所有更改並一次提交更容易。太混亂,容易出錯,而且效率低下,試圖一次性完成。

因此,代碼我結束了這個樣子的:

if (parsedItem.savedState == ItemModelSavedStateInserted) { 
    // It's a new entry. Insert it. 
    [items addObject:parsedItem]; 
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:items.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationTop]; 
} else { 
    // It's an existing entry. Find it in the portal and move it, if necessary. 
    NSUInteger foundAt = [items 
     indexOfObject:parsedItem 
       inRange:NSMakeRange(currentItemIndex, items.count - currentItemIndex - 1) 
    ]; 
    if (foundAt == currentItemIndex) { 
     // It hasn't moved! 
     if (parsedItem.savedState == ItemModelSavedStateUpdated) { 
      // It was updated, so replace it. 
      [items replaceObjectAtIndex:currentItemIndex withObject:parsedItem]; 
      [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:currentItemIndex inSection:0]] withRowAnimation:UITableViewRowAnimationMiddle]; 
     } 
    } else { 
     // It has shifted position. 
     if (foundAt != NSNotFound) { 
      // It has moved. 
      [items removeObjectAtIndex:foundAt]; 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:foundAt inSection:0]] withRowAnimation:UITableViewRowAnimationBottom]; 
     } 
     // Need to insert it. 
     [items insertObject:parsedItem atIndex:currentItemIndex]; 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:currentItemIndex inSection:0]] withRowAnimation:UITableViewRowAnimationTop]; 
    } 
} 
1

考慮使用NSSets來區分當前項目集合和新項目集合,使用單個NSMutableArray來保存有序的當前列表。您可能希望從陣列中刪除每個過期的項目,然後將每個未到期的新項目排入陣列。您不需要移除或放棄的項目是您可能需要更新的項目。