我看到一些带
的代码@property (nonatomic, readwrite, retain) id something;
他们合成了它:
@synthesize something = something_;
在构造函数中:
self.something = @"HELLO!";
我认为,上述行有效地保留了该字符串。
然而,在他们的dealloc方法中,他们这样做:
[self setSomething:nil];
我猜它没关系,因为我想当你将一个属性设置为nil时,会释放旧值。但后来,我注意到他们所做的所有其他课程都有类似
的内容[something release];
相反,所以我不再确定。这两种方式都是正确的吗?
答案 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
中不需要的操作。