iOS - viewDidUnload奇怪的调用

时间:2011-07-05 09:36:57

标签: ios cocoa-touch memory-management

我一直在阅读“初学iPhone 4开发”一书,他们有一本使用导航控制器的教程。在本教程中,我们将视图控制器(名为childController)推送到视图上。但是因为我们不想为其他类“暴露”这个控制器,所以我们没有为它创建任何访问器方法。所以在作者撰写的viewDidUnload中写道:

- (void)viewDidUnload {
    [childController release], childController = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

发布后我真的不明白逗号?这段代码实际上对我有用。我没有收到任何错误或内存泄漏。

但是我的理解不应该是这样的:

- (void)viewDidUnload {
    [childController release]; 
    childController = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

2 个答案:

答案 0 :(得分:4)

C中的逗号运算符计算其两个操作数(它们必须是表达式,而不是语句),丢弃第一个操作数并返回第二个操作数的值。在您的示例中:

[childController release], childController = nil;

编译器执行以下操作:

  1. 评估[childController release](有效地将-release发送给childController)并丢弃返回值(在-release的情况下为void);
  2. 评估childController = nil。这是一个赋值表达式,它将第二个操作数(nil)赋给第一个操作数childController,并在赋值中返回左操作数的值;
  3. 返回第二个操作数(childController的值,其中包含nil)。
  4. 由于C允许不使用表达式的值,因此将丢弃[childController release], childController = nilnil)的值。

    实际上,这相当于执行:

    [childController release]; 
    childController = nil;
    

    但是由于释放实例变量和为其分配nil之间的紧密关系,一些程序员更喜欢使用表达式。它在视觉上清晰(并且容易发现错误,例如忘记nil任务);比较:

    [childController release], childController = nil;
    [someIvar0       release], someIvar0       = nil;
    [someIvar1       release], someIvar1       = nil;
    [someIvar2       release], someIvar2       = nil;
    

    使用:

    [childController release]; 
    childController = nil;
    [someIvar0       release]; 
    someIvar0       = nil;
    [someIvar1       release]; 
    someIvar1       = nil;
    [someIvar2       release]; 
    someIvar2       = nil;
    

    这是一种风格问题。

    编辑:Eiko在评论中提到以下,不使用逗号运算符,是另一种选择:

    [childController release]; childController = nil;
    [someIvar0       release]; someIvar0       = nil;
    [someIvar1       release]; someIvar1       = nil;
    [someIvar2       release]; someIvar2       = nil;
    

答案 1 :(得分:3)

 [childController release], childController = nil;

这是简单的C,comma operator旨在“排序”表达。实际上,在这种情况下,它完全等同于:

[childController release];
childController = nil;

唯一改变的是可读性(更糟或更好,取决于......)

但一般来说,排序运算符计算最后一个语句的值(即除了最后一个操作数之外,所有操作数的值都被丢弃)。

int a, b;
int c = (a = 1), (b = 2);
执行此语句后,

c将为2。

编辑:从我添加的链接:

  

除了在for循环的第一个和第三个控制表达式之外,几乎没有任何理由使用逗号运算符,事实上,在C程序中看到的大多数逗号都不是逗号运算符。特别是,函数调用中的参数之间的逗号不是逗号运算符;它们只是标点符号,它分隔了几个参数表达式。很容易看出它们不能是逗号运算符,否则就像

这样的调用

编辑:一个更好的例子:

int a = 1;
int b = 2;
b = printf("%d, %d", a,b), a+b;

这将首先打印:

1, 2

然后将3分配给b。