【发布时间】:2015-08-04 09:35:13
【问题描述】:
在我将我的应用程序发送到 App Store 之前,我喜欢用仪器检查它是否存在内存泄漏和其他可疑的东西。有一个我似乎无法解决的 Core Data 问题,所以我决定创建一个小型测试应用程序来说明这个问题。
有什么问题?
当我将实体保存在(子)NSManagedObjectContext 中时,它会传播到其父 NSManagedObjectContext。在这个过程中,Core Data 创建了_NSObjectID 和NSTemporaryObjectID 的内部实例。出于某种原因,这些实例被遗忘了,摆脱它们的唯一方法是重置父 NSManagedObjectContext。
我的应用程序当然比这个小测试应用程序复杂得多,重置 NSManagedObjectContext 对我来说不是一个选项。
测试应用
测试应用是标准 iOS 应用,基于选中了 CoreData 选项的单一视图模板。我使用了 Objective-c 来保持它与我的生产应用程序相似。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize the Core Data stack
self.persistentStoreCoordinator = [self persistentStoreCoordinator];
// Create the a private context
self.rootContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
self.rootContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
// Create a child context
self.childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
self.childContext.parentContext = self.rootContext;
// Create a person
[self.childContext performBlockAndWait:^{
Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.childContext];
person.name = @"John Smith";
person.age = 30;
// Save the person
[self.childContext save:nil];
// Save the root context
[self.rootContext performBlockAndWait:^{
[self.rootContext save:nil];
}];
}];
return YES;
}
当您使用工具和分配工具运行上面的代码时,您会看到 Core Data 留下了一些东西。
你可以在这里找到完整的项目:https://github.com/Zyphrax/CoreDataLeak
我尝试过的事情
我尝试过 [context refreshObject:... mergeChanges:YES]、在块内添加 @autoreleasepool 和/或 [context processPendingChanges] 之类的方法,但都无济于事。清除它的唯一方法是执行[context reset](大锤方法)。
很难找到其他人报告此问题。
这篇博文看起来很相似:
http://finalize.com/2013/01/04/core-data-issues-with-memory-allocation/
我希望你们能帮助我解决这个问题。
【问题讨论】:
-
下载的项目,在仪器中运行,它没有看到任何泄漏。 XCode 6.4,部署目标 8.4,iPhone 6 模拟器。如果您可以提供其他内容,我愿意看看。
-
乔迪感谢您对此进行调查。您应该能够通过以下步骤重现它:(1) 在 Xcode 6.4 中打开项目,(2) 使用 iPad 2 / iOS 8,4 模拟器进行分配/泄漏的配置文件,(3) 泄漏仪器不会检测到任何泄漏,但是当您过滤 NSTemporaryObjectID 或 _NSObjectID 时,您应该会看到应该被释放的持久实例(类似于上面的屏幕截图,对于屏幕截图,我使用了 Xcode 7 分析器)。
标签: core-data memory-leaks instruments nsmanagedobjectcontext