避免在NSManagedObjectContext中注册对象构建(memleak)

gle*_*enc 10 memory-leaks core-data nsmanagedobjectcontext ios

我有一个内存密集型的iOS应用程序,我正在努力确保内存使用不会随着时间的推移而累积.我的应用程序有一个"主要"上下文,它存在于应用程序的生命周期中,其他较小的上下文偶尔会为后台任务生成.

我注意到的一件事是NSManagedObjects似乎长期在主上下文中保持注册,并且真正回收与从DB中提取对象相关的所有内存的唯一方法是调用[NSManagedObjectContext reset].

这当然导致内存使用量大幅下降,因为最近关闭的列表视图中的所有已注册对象都从内存中正确弹出,但是它很烦人,因为您刚刚使该上下文中注册的每个对象无效,您仍然有参考to(即仍由打开的视图引用的对象),您现在需要从数据库中重新获取所有这些对象,以避免访问无效对象的异常.

这是从NSManagedObjectContext中清除注册对象集的唯一方法,还是有更好的方法可以成功弹出您不再引用的所有已注册对象,但不会使所有仍处于活动状态的NSManagedObject失效?

Tom*_*ton 14

NSManagedObjectContext有一个内部行缓存,唯一可以清除它的方法是重置上下文.如果您实际遇到内存问题,可能会有以下几点:

  • 托管对象保留其相关对象.如果您有A来自某个其他托管对象的关系引用的托管对象B,则A即使您已释放对它的所有引用,对象也将保留在内存中.在对象B被解除分配或重新出现故障之前,它实际上不会被释放,因为它仍然会被保留B.
  • 处理此问题(以及其他内存问题)的一种方法是通过refreshObject:mergeChanges:在MOC上调用当前未使用的对象,并将第二个参数设置为NO.这会重新排除对象,即使对象返回到初始"故障"状态,卸载其属性值和关系.在此之前AB之后,重新断层B将释放与之的关系A.请记住,这将丢失所有未保存的更改B,因此请确保在必要时先保存.
  • 如果您的托管对象包含任何类型的大型二进制数据,请尝试将该数据移动到单独的实体或完全移出Core Data,以避免在不需要时将其加载到内存中.
  • reset在核心数据内存管理方面,MOC基本上是核选项.它非常有效,但是你发现它可能非常危险.除非您尚未使用从MOC加载的任何对象,否则最好避免使用.