调用 refreshObject(object, mergeChanges: NO) 时核心数据内存峰值

Posted

技术标签:

【中文标题】调用 refreshObject(object, mergeChanges: NO) 时核心数据内存峰值【英文标题】:Core Data memory spike when calling refreshObject(object, mergeChanges: NO) 【发布时间】:2015-01-12 22:32:40 【问题描述】:

在我对托管对象上下文调用 save 之后,我在我的对象上调用 refreshObject:mergeChanges:NO 以将它们变成故障。但是,这会导致内存使用量激增。

我试图将对象变成故障,以打破引用循环,从而释放内存。

如果不调用refreshObject,我的应用程序可以运行 30-40 分钟,然后它会因为消耗过多的内存而被杀死。但是,如果我在每次保存上下文后调用它,那么它只持续几分钟。

这是我的核心数据堆栈:

# Persistent Store Coordinator <--+-- privateWriterContext (NSPrivateQueueConcurrencyType)
#                                            |
#                                            +----- defaultManagedObjectContext (NSMainQueueConcurrencyType) # for the main thread
#                                                   |
#                                                   +----- backgroundManagedObjectContext (NSPrivateQueueConcurrencyType) # for bg tasks

这是我用来持久化然后刷新对象的代码

if privateWriterContext.MR_saveToPersistentStoreAndWaitWithError(error)
    privateWriterContext.performBlockAndWait(
      lambda 
        privateWriterContext.registeredObjects.each do |object|
          privateWriterContext.refreshObject(object, mergeChanges: false)
        end
      .weak!
    )
else
  # handle error
end

我已阅读其他 *** 问题,其他人似乎已成功实施 refreshObject

Core Data - break retain cycle of the parent context Core Data memory usage while importing large dataset

这是Apple's Object Lifetime Management documentation的相关sn-p:

当您在托管对象之间建立关系时,每个对象都维护对与其相关的一个或多个对象的强引用。这可能会导致强参考周期。为确保引用循环被打破,当您完成一个对象时,您可以使用托管对象上下文方法 refreshObject:mergeChanges: 将其变为故障。

【问题讨论】:

您只在私有上下文中刷新对象。它们在主线程上下文中可能仍然存在(并占用内存)。主线程显示来自托管对象的数据,因此它必须将持久存储中的数据加载到内存中。在主上下文的注册对象上调用 refreshObject 有帮助吗? 我在 privateWriterContext 或我的 defaultManagedObjectContext 上尝试了几种刷新或不刷新的组合——我可以看到已注册对象的数量下降到零。但它仍然只是加速了无限的内存增长。 【参考方案1】:

我通过删除所有使用 performBlockAndWait 并改用 performBlock 来解决此问题。

然后我使用NSNotificationCenter 在保存完成后发送消息。

【讨论】:

以上是关于调用 refreshObject(object, mergeChanges: NO) 时核心数据内存峰值的主要内容,如果未能解决你的问题,请参考以下文章

有人可以为我澄清“refreshObject:mergeChanges:YES”吗?

核心数据:refreshObject:mergeChanges:出现“缺失的链接”

托管对象上下文保存和 refreshObject:mergeChanges 有啥区别:

使用 NSManagedObjectContext refreshObject 崩溃

需要对 refreshObject:mergeChanges:YES 进行一些说明

如何在c++中,调用objective-c