iphone - 在 viewDidUnload 中设置为 nil,但在 dealloc 中释放

标签 iphone objective-c cocoa-touch memory-management

我一整天都在阅读为什么 View 应该在 viewDidUnload 中设置为 nil 并在 dealloc 中释放。所有的文章都在重复同样的事情。是的,我知道幕后说明不同,但实际差异是什么?

var = nil

  1. 如果 var 是一个保留属性,回收旧对象 var 指向的内存。
  2. 将变量设置为零。

[变量发布]

  1. 回收 var 指向的内存。
  2. 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/

相关文章:

c# - iphone 推送通知 urbanairship

iphone - 如何在 objective-c 中读取 MIME 类型的文件

iphone - 如何拉伸(stretch) iPhone UIImage 或 UIImageView 中的图像大小

ios - 我应该避免在全局队列中创建 JSContexts 吗?

ios - 快速动画旋转标签?

iphone - 如何在iPhone dev中制作NSString大写的第一个字母

objective-c - cocos2d mac项目全屏模式下警报窗口位于主窗口下方

objective-c - Objective-C中的线程和套接字

iphone - 跳过带有委托(delegate)的 View Controller

ios - 调整单元格字段 - objective-c