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例程将被正确调用,但我很困惑为什么我需要这个版本.
保存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.