为什么存储对NSManagedObject的引用会阻止它更新?

时间:2017-11-03 17:52:35

标签: ios objective-c core-data

这个问题分阶段很差,但在代码中可以更好地解释。

我们有一个核心数据堆栈,其中包含Marcus Zarra在此定义的私有和主要上下文:http://martiancraft.com/blog/2015/03/core-data-stack/

我们调用一个单独的类来执行获取请求(主上下文)并返回一个NSManagedObjects数组:

NSArray *ourManagedObjects = [[Client sharedClient].coreDataManager fetchArrayForClass:[OurObject class] sortKey:@"name" ascending:YES];

然后我们进行一些处理并存储引用:

self.ourObjects = processedManagedObjects

我们的视图包含一个UITableView,这个数据用于填充它,并且工作得很好。

我们更改了CMS上的数据,在UITableView上刷新以触发同步(私有上下文),然后调用此相同的函数来检索更新的数据。但是,即使我直接检查sqlite db它包含新数据,fetch请求也会返回与之前完全相同的数据。要显示新值,我必须重新加载应用程序。

我发现如果我没有将processedManagedObjects分配给self,那么获取请求确实会返回正确的数据,所以看起来像持有对NSManagedObject的引用会阻止它从主上下文中获取新数据。但是我不知道为什么会这样。

为了澄清,我们非常确定我们的核心数据堆没有任何问题,即使这些托管对象没有更新,其他的更新也很好,只有这一点我们存储本地参考的地方。

2 个答案:

答案 0 :(得分:2)

这听起来像是:

  • 当通过不同的托管对象上下文进行更改时,托管对象不会自动更新自身以反映持久性存储中的最新数据。
  • 因此,如果您保留对对象的引用,它们会保留已有的任何数据。
  • 另一方面,如果您不保留引用但是重新获取它们,则会获得新数据,因为没有管理对象与其旧数据相关。

您有几个选择:

  • 您可以使用refresh(_, mergeChanges:)方法或refreshAllObjects()保留引用并让您的上下文刷新托管对象。
  • 如果您的应用有意义,请使用NSFetchedResultsController并使用其委托方法获得更改通知。
  • 不要保留参考。

第一个可能是最好的 - refreshAllObjects()可能就是你想要的。根据您应用的其他详细信息,其他选项可能会更好。

答案 1 :(得分:0)

尝试将抓取请求的shouldRefreshRefetchedObjects属性设置为true。根据{{​​3}}:

  

默认情况下,当您获取对象时,即使持久性存储中的值已更改,它们也会保留其当前属性值。使用参数true调用此方法意味着在执行fetch时,将使用持久存储中的当前值更新已获取对象的属性值。