调用 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
:
这是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 崩溃