在Objective C中,为什么我的核心数据对象永远不会被释放?

Mik*_*ike 4 memory-management core-data objective-c

我很难将m个核心数据对象解除分配.我甚至尝试过我能想到的最简单的测试,并且我看到了保留计数,它似乎总是高于我的预期.我还在核心数据对象的dealloc例程上设置了一个断点,它似乎没有被调用(至少除非我专门添加其他版本).

顺便说一句,我肯定有[managedObjectContext setRetainsRegisteredObjects:NO],所以这不是问题.

这是我尝试过的一个不起作用的例子:

MobileObject *obj = [NSEntityDescription insertNewObjectForEntityForName:@"MobileObject" inManagedObjectContext:managedObjectContext];

NSLog(@"Object count after creation %d", [obj retainCount]);

NSError *error;
[managedObjectContext save:&error];

NSLog(@"Object count after saving %d", [obj retainCount]);
Run Code Online (Sandbox Code Playgroud)

每条日志消息都打印出"2".Dealloc永远不会被召唤.我希望save能够释放(或自动释放)对象,因为核心数据应该意识到它不需要保持不变.在这种情况下,如果有两个自动释放(一个来自创建,一个来自保存),则保留计数为2是有意义的,但似乎并非如此.如果我加

[obj release] 
Run Code Online (Sandbox Code Playgroud)

在我测试的最后,dealloc例程将被正确调用,但我很困惑为什么我需要这个版本.

Yuj*_*uji 6

保存CoreData上下文与发布一个逻辑上没有关系NSManagedObject.

在一个大型程序中,在程序运行时始终拥有托管对象上下文(moc)是很常见的.将对象添加到反映用户操作的上下文中以及从上下文中删除对象,并且还会偶尔保存上下文,以便将内存中的上下文同步到文件上的内容.但在这种情况下,保存上下文并不意味着你完成了上下文; 你仍然保留上下文并像保存前一样使用它.因此,保存并不意味着取消分配对象.

因此,如果要释放保留的对象,则需要显式释放它们.

但是在这种情况下,insertNewObjectForEntityName:inManagedObjectContext:返回一个自动释放的对象,如此处所写.所以除非你明确地保留它,否则你不拥有该对象.如果你没有保留,你不应该发布它.它已发布,并dealloc在适当时自动调用.

请注意,您永远不应该依赖于retainCount查看正在发生的事情.对于一个简单的对象,数量retainCount会与我们期望的一致,但对于像a这样复杂的东西NSManagedObject,框架本身需要跟踪很多事情,因此可能会retain在幕后做很多事情.例如,即使您没有显式保留对象,它也可能处于您拥有的另一个对象的关系中; 或者CoreData可能只是决定将对象保留在内存中来缓存它.

唯一要记住的是坚持标准所有权规则.如果你alloc/init或者retain你以后release或者autorelease它.

在评论中回答你的问题,让我在这里陈述基本原则:如果一个对象x需要另一个对象a,x retains a.当x使用完a,x release小号a.每个对象x都应遵循此过程,无论x是您编写的对象,还是Apple的框架提供的对象.如果每个对象都遵循这个原则,那么就没有泄漏.所以,Apple没有看到的代码遵循这一点.你的代码也应遵循这一点.

这回答了你的问题:

当我将一个子对象"添加"到父对象时,父对象会自动保留我添加的对象吗?

是的,它确实.父母需要它,所以它保留它.

如果我然后释放父对象它将释放孩子或我必须明确地这样做?

是的,父母确实释放了孩子,因为当父母被dealloc编辑时,它完成了孩子的使用,所以孩子被release编辑.

这些要点通常不会写在各个方法的文档中,因为作为规则,每个API都遵循这个基本的内存管理原则,因此不需要拼写它们.

我们鼓励您阅读Memory Manegement Rules.