Iphone 指针/内存管理的Cocoa策略

Iphone 指针/内存管理的Cocoa策略,iphone,objective-c,cocoa,cocoa-touch,Iphone,Objective C,Cocoa,Cocoa Touch,我看到很多代码,特别是在Apple示例代码中,类似于以下内容: EditingViewController *controller = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]; self.editingViewController = controller; [controller release]; 是否有任何特别原因证明上述方法比以下方法更有益: self.ed

我看到很多代码,特别是在Apple示例代码中,类似于以下内容:

   EditingViewController *controller = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
    self.editingViewController = controller;
    [controller release];
是否有任何特别原因证明上述方法比以下方法更有益:

self.editingViewController = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil];
试图了解是否有针对上述问题的策略

谢谢

你可以写:

self.editingViewController = [[[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil] autorelease];
我经常在非速度关键区域这样做。问题是该属性很可能是“retain”属性,这意味着如果不释放它,对象将泄漏


应该注意的是,autorelease比release更昂贵,但我也更喜欢代码的简洁易读性,而不是纯粹的速度。

乍一看,您的示例似乎可行,但实际上它会造成内存泄漏

按照Cocoa和Cocoa touch中的约定,使用
[[SomeClass alloc]initX]
[SomeClass newX]
创建的任何对象的保留计数均为1。当您处理完新实例时,您负责调用
[someClassInstance release]
,通常是在
dealloc
方法中

当您将新对象指定给属性而不是实例变量时,这会变得棘手。大多数属性定义为
retain
copy
,这意味着它们要么在设置时增加对象的retain计数,要么复制对象,保持原始对象不变

在您的示例中,您的
.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
是一个普通的旧实例变量,没有编译器生成的任何保留或复制代码


另请参见

即使它是一个复制属性,您也会泄漏。我认为您错过了最后对自动释放的调用。@property(retain)EditingViewController*EditingViewController;//(2) 属性设置器将保留计数增加到2 self.editingViewController=/(1)创建的新对象的保留计数为1[[editingViewController alloc]initWithNibName:@“EditingView”bundle:nil];//哎呀!保留计数现在为2。这不是真的。编译器创建的setter方法将释放作为参数传递的对象,并保留该属性。因此保留计数将为1,没有问题。