iphone - 关于过度释放的问题

时间:2010-10-27 23:29:08

标签: iphone memory-management memory-leaks

在任何iphone模板UIViewController类中,您都会看到:

- (void)viewDidUnload {

    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

但是如果我在viewDidUnload中设置self.myOutlet = nil,并且我在dealloc方法中也有[self.myOutlet release],那么就不会过度释放self.myOutlet,因为将它设置为nil已经设置了它保持计数为零?

如果我不在dealloc()中释放它,Leaks报告内存泄漏,因为它从未看到self.myOutlet被释放,假设我在头文件中有这样的东西:

@property (nonatomic, retain) UIView *myOutlet;

3 个答案:

答案 0 :(得分:2)

如果您在self.myOutlet中将nil设置为viewDidUnload,则dealloc[myOutlet release]的通话只会向nil发送一条发布消息。向nil发送消息是完全可以接受的。没有什么不好的事情发生,你不会过度释放任何东西。

需要注意的是发布myOutlet viewDidUnload引用的对象,而myOutlet设置为nil。在这种情况下,您将在dealloc中遇到崩溃。为什么?因为myOutlet仍然会引用myOutlet对象占用的内存位置,并且您的dealloc方法会尝试发送当前位于该内存位置的任何内容release消息。

答案 1 :(得分:1)

发出内存警告时会调用

-(void)viewDidUnload,在视图的完整销毁中调用-(void)dealloc(这些不一样)。因此,你应该做两件事

- (void)viewDidUnload {

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

编辑:詹姆斯所说的更深刻。

干杯!

答案 2 :(得分:1)

这不是具有保留计数的变量;这是对象。执行self.something = nil时,它确实释放了对象 - 并将变量设置为指向nil。因此,发送到release的任何其他self.something邮件都不会转到原始对象。相反,他们会转到新值nil,它会高兴地忽略您告诉它的任何内容。