在viewDidUnload中设置为nil,但在dealloc中释放 [英] Set to nil in viewDidUnload, but release in dealloc

查看:134
本文介绍了在viewDidUnload中设置为nil,但在dealloc中释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我整天都在阅读有关为什么在viewDidUnload中将视图设置为nil并在dealloc中发布的原因。所有文章都在继续重复同样的事情。是的,我知道幕后的说明是不同的,但实际的区别是什么?

I've been reading all day about why views should be set to nil in viewDidUnload and released in dealloc. All the articles keep on repeating the same thing. Yes, I know the behind-the-scene instructions are different, but what are the practical differences?

var = nil


  1. 如果var是一个保留的属性,回收旧对象var所指向的内存。

  2. 将var设置为nil。

[var release]


  1. 回收内存变量指向。

  2. var现在指向空白,相当于nil

对我来说,回收内存的两种方式都有相同的最终结果。那么为什么一个在另一个呢?那里的每本书都告诉我在 viewDidUnload 中设置为nil,并在 dealloc 中发布。如果视图在 viewDidUnload 中发布并且在 dealloc 中填充,则有人应该指出会发生的坏事。

To me, both ways of reclaiming memory have the same end result. So why do one over the other? Every book out there tells me to set to nil in viewDidUnload and release in dealloc. Someone should point out the bad things that would happen if a view was released in viewDidUnload and nilled in dealloc.

.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 来查看属性访问的结果。这与编写 [[自我标签]发布] 完全相同,我希望你能认识到这是错误的。

is absolutely wrong regardless of where you call it. You should never call -release on the results of property access. This is exactly the same as writing [[self label] release], which I hope you can recognize as being wrong.

您的代码示例应如下所示:

Your code sample should look like the following:

- (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通知。

If we look at -viewDidUnload first, it's pretty simple. self.label = nil; is correct. Similarly correct would be [self setLabel:nil];. And while not quite as good, it would also be acceptable to write [label release], label = nil;. This last form isn't as good because it bypasses the setter method, which may be doing more things than simply releasing the property (e.g. it may maintain internal state that cares about the value of the property). It also bypasses KVO notifications.

这里真正的问题是你在 -dealloc 中做了什么。很多人建议说 self.label = nil; 是完全没问题的,实际上,这种方法大部分都可以使用。问题是,其余的时间会导致细微的错误。调用setter有两件事可以做。首先,如果手动实现setter方法,它可能会导致类中的副作用(即使您没有自己实现setter,也可能是子类)。第二是它可以播放KVO通知。当你在 -dealloc 时,这两件事都不合适。通过直接释放ivar,如 [label release]; ,您可以避免潜在的副作用和KVO通知。

The real question here is what you do in -dealloc. Many people suggest that it's perfectly fine to say self.label = nil;, and practically speaking, this will work most of the time. The problem is, the rest of the time it will cause subtle bugs. There are two things that calling the setter can do. The first is it can cause side effects in your class if the setter method is implemented manually (even if you're not implementing the setter yourself, a subclass might). The second is it can broadcast KVO notifications. Neither of these things are desired when you're in -dealloc. By releasing the ivar directly, as in [label release];, you avoid both the potential side effects and the KVO notifications.

这篇关于在viewDidUnload中设置为nil,但在dealloc中释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆