请参阅以下代码:
- (void) setSomeThing:(NSString *) someThingNew
{
if(someThing!=someThingNew)
{
[someThingNew retain];
[someThing release];
someThing = someThingNew;
}
}
... ...
- (void) dealloc
{
[someThing release];
[super dealloc];
}
@end
setter方法中的setter someThingNew
参数为retain
,表示其保留计数为1。
问题在于:someThingNew
应release
?
或者因为someThing
和someThingNew
指向同一个对象,而dealloc
方法someThing
已经release
所以someThingNew
点到nil
?
答案 0 :(得分:1)
是someThingNew应该发布吗?
不,因为现在someThing
和someThingNew
指向同一地址。通过在dealloc中释放someThing
(并且将其定为安全,但这是另一个问题),您可以平衡设置器中的保留。一切都很好!*
*旁注:NSString
的实例通常是copy
'd,而不是retain
d,因此如果您不小心通过NSMutableString
并不重要对它来说。
答案 1 :(得分:0)
每当调用setter方法时,都会保留someThingNew并释放someThing。然后someThingNew的新地址存储在someThing中,使保留计数为1。
这将保留在类中,直到对象本身未被释放。调用dealloc后,someThingNew的指针被释放,使保留计数为0。
答案 2 :(得分:0)
您的代码是正确的:如果您想使其成为“强”变量,则setter应保留该对象。但是你不必释放它:它不是制定者的责任范围。因此,在您调用setter的代码中,您将:
你做得很好,除了字符串通常被复制的事实,因为多态性有效,指针可能指向一个可变的字符串对象,因此它可能会从一个时刻变为另一个。
示例:
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
NSString* newString= [[NSMutableString alloc]initWithString: @"Hello"]; // Retain count 1.
[newString autorelease]; // Still 1 as retain count, but it will be decreased
// when the pool will be drained.
[object setSomeThing: newString]; // Retain count 2.
[pool drain]; // Retain count 1
在这个例子中,你清楚地看到为什么你需要复制对象而不是保留它:它是一个可变的字符串,所以它可以随时修改。
复制对象
如果你复制了对象,那么你调用方法的方式(所以上面的代码)不会改变,它只会改变方法的实现。像这样:
- (void) setSomeThing:(NSString *) someThingNew
{
if(someThing!=someThingNew)
{
[someThing release]; // Retain count decreased by 1.
someThing = [someThingNew copy]; // Retain count 1.
}
}
... ...
- (void) dealloc
{
[someThing release];
[super dealloc];
}
@end