我一整天都在阅读为什么 View 应该在 viewDidUnload 中设置为 nil 并在 dealloc 中释放。所有的文章都在重复同样的事情。是的,我知道幕后说明不同,但实际差异是什么?
var = nil
- 如果 var 是一个保留属性,回收旧对象 var 指向的内存。
- 将变量设置为零。
[变量发布]
- 回收 var 指向的内存。
- var 现在指向空,相当于 nil
对我来说,两种回收内存的方式都有相同的最终结果。那么为什么一个比另一个呢?那里的每本书都告诉我在 viewDidUnload
中设置为 nil 并在 dealloc
中释放。有人应该指出如果在 viewDidUnload
中释放 View 并在 dealloc
中取消 View 会发生的坏事。
.h
#import <UIKit/UIKit.h>
@interface DisclosureDetailController : UIViewController {
UILabel* label;
}
@property (nonatomic, retain) IBOutlet UILabel* label;
@end
.m
#import "DisclosureDetailController.h"
@implementation DisclosureDetailController
@synthesize label;
- (void)viewDidUnload {
self.label = nil;
// OR [self.label release];
[super viewDidUnload];
}
- (void)dealloc {
[self.label release];
// OR self.label = nil;
}
最佳答案
先行,行
[self.label release];
是绝对错误的,不管你在哪里调用它。您应该永远不要对属性访问的结果调用-release
。这与编写 [[self label] release]
完全一样,我希望你能认识到这是错误的。
您的代码示例应如下所示:
- (void)viewDidUnload {
self.label = nil;
[super viewDidUnload];
}
- (void)dealloc {
[label release];
[super dealloc];
}
如果我们先看一下 -viewDidUnload
,它非常简单。 self.label = nil;
是正确的。同样正确的是 [self setLabel:nil];
。虽然不太好,但编写 [label release], label = nil;
也是可以接受的。最后一种形式不太好,因为它绕过了 setter 方法,这可能比简单地释放属性做更多的事情(例如,它可能维护关心属性值的内部状态)。它还会绕过 KVO 通知。
这里真正的问题是您在 -dealloc
中做了什么。许多人建议说 self.label = nil;
非常好,实际上,这在大多数情况下都有效。问题是,其余时间它会导致细微的错误。调用 setter 可以做两件事。首先,如果手动实现 setter 方法,它可能会在您的类中产生副作用(即使您没有自己实现 setter,子类也可能)。第二个是它可以广播 KVO 通知。当您在 -dealloc
中时,这些都不是您想要的。通过直接释放 ivar,如 [label release];
,您可以避免潜在的副作用和 KVO 通知。
关于iphone - 在 viewDidUnload 中设置为 nil,但在 dealloc 中释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5737312/