阻止NSManagedObject引用更新UITableViewCell

背景资料:

我们有一个应用程序,可以从Core Data中填充tableviews。 这个应用程序有一个实现的同步机制,它在后台上下文中更新CoreData数据,并在完成后自动合并回主上下文。

为了使示例简单,让我们假设一个Message和一个Comment ‘实体’,其中一个消息可以有零个或多个注释。 我们已经为所有实体子类化了NSManagedObjects ,因此在Message类上有一个名为comments (属性为Set )的属性。

该应用程序的要求是视图可能在导航到新屏幕时更新屏幕上的数据。 这意味着当您在屏幕上并在后台进行任何数据更新时,可见数据应保持不变

我们的MessageViewcontroller有一个私有属性message ,它将在viewDidLoad填充。 在cellForRowAt indexPath我们使用cell.message = message.comments[indexPath.row]

问题:

这样做的问题是,如果我们在后台上下文中更新了注释,并将其合并回主上下文,则在tableview中“向上和向下滚动”(再次触发cellForRowAt indexPath )将使用更新的文本更新单元格。

这是有道理的,因为我们的message属性是一个表示CoreData中数据的引用。

题:

如何防止message变量更新? 或者换句话说:在加载视图控制器时,如何保留消息对象(及其关系)的“快照”?

解?

我认为唯一可行的解​​决方案是创建一个具有相同属性的结构,并在加载视图时填充该结构。 我真的不喜欢这种方法,因为我们的模型比这个Message示例更复杂,并且有许多关系,递归等。

从iOS 9开始,您可以使用queryGenerationTokens 。 生成令牌是指向核心数据在特定时间处于的状态的指针。 您创建一个新的主队列managedObjectContext直接附加到持久性存储协调器,并将其queryGenerationToken设置为当前的。 还将automaticallyMergesChangesFromParent设置为false。 在这个新上下文中执行提取,您将不会从核心数据发生的任何其他更新或更改。 当用户离开页面时,您可以丢弃上下文,当他返回页面时,您可以创建一个新页面。 上下文不是资源密集型的,您不应该害怕根据需要创建和丢弃它们。