谁应该负责释放setter的参数?

时间:2013-03-05 13:37:05

标签: objective-c setter

请参阅以下代码:

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

问题在于:someThingNewrelease

或者因为someThingsomeThingNew指向同一个对象,而dealloc方法someThing已经release所以someThingNew点到nil

3 个答案:

答案 0 :(得分:1)

  

是someThingNew应该发布吗?

不,因为现在someThingsomeThingNew指向同一地址。通过在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