同步更新 UITableView 的模式?
Posted
技术标签:
【中文标题】同步更新 UITableView 的模式?【英文标题】:Pattern for Updating UITableView on Sync? 【发布时间】:2010-10-09 06:08:20 【问题描述】:我正在开发一个提要阅读器 ios 项目。提要条目按时间倒序在UITableView
中列出。启动时,它们会从数据库加载到数组中。
当应用同步到订阅源时,它会为新的事物顺序创建一个新数组,然后更新表格,将新数组与旧数组进行比较,以确定要删除、更新或插入哪些单元格。我这样做的方式很幼稚,因此效率很低:大量调用indexOfObject:
以查看一个数组中的项目是否在另一个数组中。两次。每个新条目添加到新数组时一次,查看它是否在旧数组中,然后对旧数组中的每个条目执行一次,查看它是否 not 在新数组中。
作为一名数据库专业人士,这种设计冒犯了我。
但这一定是一种很常见的模式。什么是最合适、最可可的方式来解决这个问题?
【问题讨论】:
【参考方案1】:原来我错了。我找到的解决方案是像往常一样在数组中添加和删除项目,然后根据添加、更改或移动的每一行调用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];
【讨论】:
【参考方案2】:考虑使用 NSSet 来区分当前项集和新项集,并使用单个 NSMutableArray 来保存有序的当前列表。您可能希望从数组中删除每个过期的项目,然后将每个未过期的新项目分类到数组中。您既不需要删除也不需要重新排序的项目是您可能想要更新的项目。
【讨论】:
以上是关于同步更新 UITableView 的模式?的主要内容,如果未能解决你的问题,请参考以下文章
UITableView 的 shouldIndentWhileEditingRowAtIndexPath: 没有被调用
Core Data 应用程序中的 UITableView 不会更新第二个设备的主视图,除非重新启动应用程序,并使用 iCloud 同步
UITableView处于编辑模式时如何更新减号的背景? [复制]