将保留的财产设置为零吗?

时间:2014-06-05 01:52:09

标签: ios objective-c

我看到一些带

的代码
@property (nonatomic, readwrite, retain) id something;

他们合成了它:

@synthesize something = something_;

在构造函数中:

self.something = @"HELLO!";

我认为,上述行有效地保留了该字符串。

然而,在他们的dealloc方法中,他们这样做:

[self setSomething:nil];

我猜它没关系,因为我想当你将一个属性设置为nil时,会释放旧值。但后来,我注意到他们所做的所有其他课程都有类似

的内容
[something release];

相反,所以我不再确定。这两种方式都是正确的吗?

3 个答案:

答案 0 :(得分:2)

简短回答:使用ARC。它会照顾你的这些东西。它更容易出错,并且与手动引用计数一样快。

更长的答案:

如果您使用保留属性,那么将属性设置为nil是正确的做法。

像这样:

self.something = nil;

这是有效的,因为保留属性的setter首先释放旧值,然后保留新值并将其分配给属性的iVar。由于新值为零,因此保留不起作用。

如果在你的第二个例子中:

[something release];

something是属性的iVar,如果从对象的dealloc方法的代码中调用它,则此代码将导致将来崩溃。原因是这会释放对象,但不会将iVar归零。稍后,当释放具有某个属性的对象时,将触发其dealloc方法。 dealloc方法中的代码应该尝试释放对象的保留属性。将释放发送到已经解除分配的对象会导致崩溃。

在您的情况下,您询问dealloc方法中的代码。在dealloc中,调用[something release]并将属性设置为nil与释放对象具有相同的结果。但是,调用setter可能更安全,因为自定义setter有时会有其他代码带有额外的“副作用”。由于您正在编写dealloc方法,因此您应该是该类的作者,并且应该知道setter方法中的任何特殊代码。

现在,如果something是实例变量而不是属性,那么正确的做法是

[something release]
something = nil;

2014年6月5日编辑,讨论dealloc方法中的代码案例。

答案 1 :(得分:1)

两者都是正确的,当[self setSomething:nil];被释放为0 retainCount然后dealloc时,something会更好。这可以防止使用something与BAD_EXE崩溃。

正如mifki所说,如果使用[set setSomething:nil],就会调用setter;所以这取决于你在setter方法中做了什么,一个好的setter应该关心设置值为nil,并正确处理这个案例,并且不会是不希望的。

即使setter方法的工具总是无法设置为nil,更好的发布方式应该是:

[something_ release], something_ = nil;  //this should be safely release always

答案 2 :(得分:1)

最好使用[something_ release]。这不会导致调用setter,否则可能会导致执行dealloc中不需要的操作。