如何知道谁将拥有所有权?

时间:2010-07-06 10:50:10

标签: objective-c cocoa

食谱示例

RecipeAddViewController *addController = [[RecipeAddViewController alloc]
                  initWithNibName:@"RecipeAddView" bundle:nil];
addController.delegate = self;

Recipe *newRecipe = [NSEntityDescription 
                  insertNewObjectForEntityForName:@"Recipe" 
                  inManagedObjectContext:self.managedObjectContext];
addController.recipe = newRecipe;

UINavigationController *navigationController = [[UINavigationController alloc]
                  initWithRootViewController:addController];
[self presentModalViewController:navigationController animated:YES];

[navigationController release];
[addController release];
  1. presentModalViewController和initWithRootViewController保留其参数并取得所有权。然后释放了两个对象,证明有人取得了所有权。因此,一般来说,如何知道哪个消息将获得所有权,以释放相应的对象?

  2. newRecipe未发布,因为托管对象的生命周期不属于我的业务,​​这个陈述是否正确?

  3. UPD: 抱歉#2的答案是,它由addController保留,然后在addController的dealloc中发布。

2 个答案:

答案 0 :(得分:3)

规则最简单的形式是:

  

如果保留,则将其释放。

然而,保留我的意思是“增加保留计数”,因此创建一个新对象(除非它被自动释放)也算作保留。

所以:

  1. 如果您致电alloc,则将其发布。
  2. 如果您致电copy,则将其发布。
  3. 如果您致电retain,则将其发布。
  4. 除了这三种情况之外,您不必担心发布(假设您使用的第三方库遵循命名约定)。但是,如果您必须知道保留的内容以及未保留的内容,您可以查看相关课程的文档。

    对于你的例子:

    1. 工厂方法(如[NSString stringWithFormat:])创建自动释放的对象。根据经验,如果它是一个以类名开头的类方法,它将返回一个自动释放的对象。

    2. insertNewObjectForEntityForName:inManagedObjectContext:返回一个自动释放的对象。这是documentation for NSEntityDescription

    3. 几乎从不保留代表,以防止保留周期。

    4. 除了代表之外,您无需关心课程中发生的事情。如果您将属性传递给它,那么在需要时保留或复制它是它的工作。您需要关心的是平衡您的保留和释放。

答案 1 :(得分:1)

Cocoa Memory Management rules告诉你所有你需要知道的事情。

回答你的问题:

  1. 您不关心其他对象在发布/保留方面做了什么。假设他们遵守规则,你会没事(或者是他们代码中的错误)。

  2. 您不应该发布newRecipe,因为您没有使用new,alloc或包含副本的方法获取它。你也没有保留它。