为什么iPhone示例代码使用了这么多中间变量?

bea*_*ain 3 memory-management objective-c simplification ios

我目前正在研究Apress的"开始iPhone 3开发".他们在示例应用程序中使用的标准类似于以下代码:

- (void)viewDidLoad {
    BlueViewController *blueController = [[BlueViewController alloc] 
                                         initWithNibName:@"BlueView" bundle:nil];
    self.blueViewController = blueController;
    [self.view insertSubview:blueController.view atIndex:0];
    [blueController release];
}
Run Code Online (Sandbox Code Playgroud)

8.14.11 UPDATE(附加信息)
blueViewController声明如下:

@property (retain, nonatomic) BlueViewController *blueViewController;
Run Code Online (Sandbox Code Playgroud)

每当他们执行一个alloc他们把它放在一些临时变量(这里blueController)然后他们分配它,然后他们释放它.这个临时变量对我来说似乎是多余的.
我将代码简化如下:

- (void)viewDidLoad {
    self.blueViewController = [[BlueViewController alloc] 
                              initWithNibName:@"BlueView" bundle:nil];
    [self.view insertSubview:blueViewController.view atIndex:0];
}

- (void)dealloc {
    [blueViewController release];
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

我的修改后的代码在iPhone模拟器中运行完全相同.现在,我知道规则,如果你分配一些东西,你需要释放它.我在我的dealloc方法中涵盖了这一点.但是直接在ViewDidLoad(alloc被调用的函数)中释放是否有一些优势?或者release在这样的dealloc方法中同样可以吗?
谢谢你的帮助,
-j

alb*_*amg 8

假设blueViewController是一个retain属性,临时变量不是多余的.您的简化会造成内存泄漏.来自第二个片段的声明泄漏:

self.blueViewController = [[BlueViewController alloc] 
                          initWithNibName:@"BlueView" bundle:nil];
Run Code Online (Sandbox Code Playgroud)

在所有权方面,您拥有alloc-init返回的对象,然后属性访问者再次声明对象的所有权,从而导致对象被过度保留.

使用临时变量可以解决此问题.另一种选择是使用autorelease:

self.blueViewController = [[[BlueViewController alloc] 
                          initWithNibName:@"BlueView" bundle:nil] autorelease];
Run Code Online (Sandbox Code Playgroud)

请注意,在此语句之后,您实际拥有该对象,并且必须在dealloc中释放它.


你没有提到财产blueViewController是如何申报的.总之,无论二传手的语义(retain,copy,assign),这种说法是错误的.我已经解释了最可能出现的情况:retain.让我们来看看其他两个可能性(不考虑它们是否有意义):

  • 如果blueViewController恰好是一个copy财产,该声明也会泄漏.属性访问器复制原始对象,现在该属性包含指向副本的指针,并且您丢失了原始对象的跟踪,并立即将其泄漏.

  • 最不可能的情况是,这blueViewController是一个assign属性,因为这很可能是错误的,你真的想要retain.但是,无论如何,assign属性是针对您不拥有的对象,例如委托,并且您不应该释放它们.您分配一个对象,你拥有它,所以要么你泄漏,或错误地释放指派属性.