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

Ios 为什么存储对NSManagedObject的引用会阻止它更新?,ios,objective-c,core-data,Ios,Objective C,Core Data,这个问题的阶段性很差,但这可以在代码中得到更好的解释 我们有一个核心数据栈,其中包含Marcus Zarra在此处定义的私有和主上下文: 我们调用一个单独的类来执行提取请求(主上下文)并返回NSManagedObject数组: NSArray *ourManagedObjects = [[Client sharedClient].coreDataManager fetchArrayForClass:[OurObject class] sortKey:@"name" ascending:YES];

这个问题的阶段性很差,但这可以在代码中得到更好的解释

我们有一个核心数据栈,其中包含Marcus Zarra在此处定义的私有和主上下文:

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

NSArray *ourManagedObjects = [[Client sharedClient].coreDataManager fetchArrayForClass:[OurObject class] sortKey:@"name" ascending:YES];
然后,我们进行一些处理并存储一个引用:

self.ourObjects = processedManagedObjects
我们的视图包含一个UITableView,该数据用于填充它,工作正常

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

我发现,如果不将ProcessedManagedObject分配给self,则fetch请求确实会返回正确的数据,因此保留对NSManagedObject的引用似乎会阻止它从主上下文获取新数据。但是我不知道为什么会这样


为了澄清,我们非常确定我们的核心数据堆栈没有问题,即使这些托管对象没有被更新,其他对象也在被更新,只有这一个存储了本地引用。

这听起来像是发生了什么:

  • 当通过不同的托管对象上下文进行更改时,托管对象不会自动更新自身以反映持久存储中的最新数据
  • 因此,如果您保留对对象的引用,它们将保留它们已经拥有的任何数据
  • 另一方面,如果不保留引用,而是重新获取它们,则会获得新数据,因为没有托管对象与其旧数据挂在一起
您有几个选择:

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

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

尝试将获取请求的
shouldRefreshRefetchedObjects
属性设置为
true
。根据:

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


刷新所有对象使其工作,太棒了!我假设调用此方法会对性能产生影响,但是否还有其他缺点?潜在的缺点是,如果刷新的对象有任何未保存的更改,则可能会丢失这些更改。使用
refresh(\uu,mergeChanges:)
您可以根据第二个参数控制它。使用
refreshAllObjects()
您将丢失刷新对象上未保存的更改。好的,谢谢。所有更改都是在私有上下文上进行的,只有在保存完成后才会执行提取请求。