0

请看代码如下:

- (void) setSomeThing:(NSString *) someThingNew
{
     if(someThing!=someThingNew)
     {
         [someThingNew retain];
         [someThing release];
         someThing = someThingNew;
     }
 }

 ... ...
 - (void) dealloc
 {
     [someThing release];
     [super dealloc];
 }
@end

setter 的参数someThingNew已经retain在 setter 方法中,表示它的保留计数为 1。

这里的问题是:someThingNew应该release吗?

还是因为someThingsomeThingNew指向同一个对象,而在dealloc方法someThing中一直release这么someThingNew指向nil

4

3 回答 3

1

someThingNew 应该发布吗?

不,因为现在someThingsomeThingNew指向同一个地址。someThing通过在 dealloc 中释放(并为安全起见将其取消,但这是另一个问题),您可以平衡 setter 中的保留。一切正常!*

*旁注:在setter中的实例NSString通常是copy'd,而不是retaind,所以如果你不小心传递给它也没关系NSMutableString

于 2013-03-05T13:55:18.667 回答
0

每当调用 setter 方法时,都会保留 someThingNew 并释放 someThing。然后将 someThingNew 的新地址存储在 someThing 中,使保留计数为 1。

这将保留在类中,直到对象本身未被释放。一旦调用了 dealloc,someThingNew 的指针就会被释放,从而使保留计数为 0。

于 2013-03-05T13:44:57.243 回答
0

您的代码是正确的:如果您想让它成为“强”变量,setter 应该保留该对象。但是您不必释放它:这不是 setter 的职责范围。因此,在您调用 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
于 2013-03-05T14:38:55.117 回答