我看到很多代码,特别是苹果示例代码,类似于以下代码:

   EditingViewController *controller = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
    self.editingViewController = controller;
    [controller release];

是否有任何理由特别证明上述方法有利于:
self.editingViewController = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];

试图了解是否有上述策略。
谢谢!

最佳答案

乍一看,您的示例似乎可以工作,但实际上它会造成内存泄漏。
根据cocoa和cocoa touch中的约定,使用[[SomeClass alloc] initX][SomeClass newX]创建的任何对象都将以1的保留计数创建。当您完成新实例的处理时,您负责调用[someClassInstance release],通常是在dealloc方法中。
当您将新对象分配给一个属性而不是一个实例变量时,这就变得棘手了。大多数属性都被定义为retaincopy,这意味着它们要么在设置时增加对象的保留计数,要么复制对象,使原始对象保持不变。
在您的示例中,您的.h文件中可能包含以下内容:

@property (retain) EditingViewController *editingViewController;

所以在你的第一个例子中:
EditingViewController *controller =
    [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
// (1) new object created with retain count of 1

self.editingViewController = controller;
// (2) equivalent to [self setEditingViewController: controller];
// increments retain count to 2

[controller release];
// (3) decrements retain count to 1

但对于第二个例子:
// (2) property setter increments retain count to 2
self.editingViewController =

    // (1) new object created with retain count of 1
    [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];

// oops! retain count is now 2

通过在将新对象传递给setter之前对其调用autorelease方法,可以要求autorelease池取得该对象的所有权,并在将来的某个时间释放它,因此在一段时间内,该对象有两个所有者来匹配其保留计数,并且一切都非常棒。
// (3) property setter increments retain count to 2
self.editingViewController =

    // (1) new object created with retain count of 1
    [[[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]

        // (2) give ownership to autorelease pool
        autorelease];

// okay, retain count is 2 with 2 owners (self and autorelease pool)

另一个选择是直接将新对象分配给实例变量,而不是属性设置器。假设您的代码名为基础实例变量editingViewController
// (2) assignment to an instance variable doesn't change retain count
editingViewController =

    // (1) new object created with retain count of 1
    [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];

// yay! retain count is 1

这是代码中微妙但关键的区别。在这些示例中,self.editingViewController = x[self setEditingViewController: x]的语法糖,但editingViewController是一个普通的旧实例变量,没有编译器生成的任何保留或复制代码。
另见Why does this create a memory leak (iPhone)?

09-26 03:29