Core data 核心数据:NSObjectID和NSTemporaryObjectID泄漏

Core data 核心数据:NSObjectID和NSTemporaryObjectID泄漏,core-data,memory-leaks,instruments,nsmanagedobjectcontext,Core Data,Memory Leaks,Instruments,Nsmanagedobjectcontext,在我将我的应用程序发送到应用商店之前,我喜欢用仪器检查它是否有内存泄漏和其他可疑的东西。有一个核心数据问题我似乎无法解决,因此我决定创建一个小型测试应用程序来说明这个问题 有什么问题吗? 在(子)NSManagedObjectContext中保存实体时,它将传播到其父NSManagedObjectContext。在此过程中,核心数据创建\u NSObjectID和NSTemporaryObjectID的内部实例。由于某些原因,这些实例被遗留下来,摆脱它们的唯一方法是重置父NSManagedObj

在我将我的应用程序发送到应用商店之前,我喜欢用仪器检查它是否有内存泄漏和其他可疑的东西。有一个核心数据问题我似乎无法解决,因此我决定创建一个小型测试应用程序来说明这个问题

有什么问题吗?

在(子)NSManagedObjectContext中保存实体时,它将传播到其父NSManagedObjectContext。在此过程中,核心数据创建
\u NSObjectID
NSTemporaryObjectID
的内部实例。由于某些原因,这些实例被遗留下来,摆脱它们的唯一方法是重置父NSManagedObjectContext

我的应用程序当然比这个小测试应用程序复杂得多,重置NSManagedObjectContext对我来说不是一个选项

测试应用程序

测试应用程序是基于选中CoreData选项的单视图模板的标准iOS应用程序。我使用objective-c使其与我的生产应用程序相似

-(BOOL)应用程序:(UIApplication*)应用程序使用选项完成启动:(NSDictionary*)启动选项{
//初始化核心数据堆栈
self.persistentstorecomporator=[self-persistentstorecomporator];
//创建一个私有上下文
self.rootContext=[[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
self.rootContext.persistentStoreCoordinator=self.persistentStoreCoordinator;
//创建子上下文
self.childContext=[[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
self.childContext.parentContext=self.rootContext;
//创造一个人
[self.childContext执行锁定和等待:^{
Person*Person=[NSEntityDescription insertNewObjectForEntityForName:@“Person”在托管对象上下文中:self.childContext];
person.name=@“John Smith”;
人.年龄=30;
//救人
[self.childContext保存:nil];
//保存根上下文
[self.rootContext执行锁定和等待:^{
[self.rootContext保存:nil];
}];
}];
返回YES;
}
当您使用工具和分配工具运行上面的代码时,您可以看到核心数据留下了一些东西

您可以在此处找到完整的项目:

我尝试过的事情

我尝试过像
[context refreshObject:…mergeChanges:YES]
,在块内添加
@autoreleasepool
和/或
[context processPendingChanges]
这样的方法,但都没有用。清理的唯一方法是执行
[context reset]
(大锤式方法)

很难找到其他人报告这个问题。 这篇博文似乎很相似:


我希望你们能帮我

这是我看到的,与你的非常相似

然而,我不知道我会担心,除非你看到很多这样的东西,它们永远不会消失。我假设核心数据的内部(包括行缓存)正在进行某种对象缓存

另一方面,我的核心数据使用在过去一两年中发生了一些变化

除非它是一个非常简单的应用程序,否则我几乎从不在子上下文中创建新对象。我将获取并修改它们,但如果我最终创建了一个新对象,我会确保这是在兄弟上下文中完成的

但是,如果您稍微修改代码,请在初始保存之前添加此行(使用适当的错误处理-它返回
BOOL

NSArray *inserted = self.childContext.insertedObjects.allObjects;
[self.childContext obtainPermanentIDsForObjects:inserted error:&error];
你应该得到类似于这个instruments报告的东西,它显示了所有创建为瞬态的对象

因此,我不一定认为这是永久性泄漏,因为一旦我强制上下文转换为永久ID,对象就会消失。然而,谁知道他们将这些对象ID对象缓存多久呢


通常,当我在包含层次结构的上下文中创建对象时,我总是首先获得永久ID(出于许多原因)。但是,正如我前面所说,我通常在直接创建到持久存储的上下文中创建新对象(因为我必须处理与层次结构临时对象ID相关的其他问题,特别是在使用多个不相关的上下文时)。

下载的项目,在工具中运行,它也没有发现任何泄漏。XCode 6.4,部署目标8.4,iPhone6模拟器。如果你能提供一些其他的东西,我很乐意去看看。乔迪,谢谢你调查这件事。您应该能够通过以下步骤复制它:(1)在Xcode 6.4中打开项目,(2)使用iPad 2/iOS 8,4模拟器配置文件进行分配/泄漏,(3)泄漏工具不会检测到任何泄漏,但是当您在NSTemporaryObjectID或_NSObjectID上进行筛选时,您应该会看到应该已解除分配的持久实例(与上面的截图类似,对于截图,我使用了Xcode 7分析器).Hi Jody,谢谢你的回答!我将尝试使用GetainPermanentidsforObject方法。如果你创建了一个直接连接到持久存储的上下文,你如何通知其他上下文在你的上下文中所做的更改?核心数据将自动发送
NSManagedObjectContextWillSaveNotification
NSManagedObjectContextDidSaveNotification
在保存上下文时发送到默认通知中心。同样,只要对上下文进行更改,
NSManagedObjectContextObjectsIDChangeNotification
也会在上下文进行更改时发送。有关SO的许多问题以及如何执行此操作的其他许多信息。如果您发现自己被难倒,请发布另一个问题-您好请给我一个指导我的评论,我来看看。