2013-03-05 79 views
0

请参阅代码如下:谁应该负责释放setter的参数?

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

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

二传手someThingNew的参数已经retain在setter方法,这意味着它的保留计数为1

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

还是因为someThingsomeThingNew指向同一个对象,并在dealloc方法someThing一直release所以someThingNewnil

+3

Objective C的内存管理指南:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html – Kreiri 2013-03-05 13:42:59

回答

1

是someThingNew应该释放吗?

没有,因为现在someThingsomeThingNew指向相同的地址。通过在dealloc中释放someThing(并且无法保证安全,但这是另一个问题),您可以在setter中平衡保留。一切顺利精细*

*旁注:中NSString实例通常copy“d,不retain d,在制定者,所以如果你不小心通过NSMutableString它也没关系。

+0

首先谢谢你,但是什么是“itr”呢? – Michael 2013-03-05 22:31:22

+0

我的歉意,我不小心键入了'r'而不是一段时间。 – CodaFi 2013-03-05 22:53:58

+0

旁注是伟大的:) – 2013-03-06 02:05:31

0

每当你的setter方法被调用someThingNew被保留,someThing被释放。然后someThingNew的新地址被存储在一些Thing中,使得保留计数为1.

这将一直保留在类中,直到对象本身未被释放为止。一旦dealloc被称为someThingNew的指针被释放,使得保留计数为0.

+0

因此,这意味着[SOMETHING发布]实际上释放一些Thing和一些ThingNew。非常感谢。 – Michael 2013-03-05 22:36:37

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 
+0

在第一个地方我会问两个问题第一个是这个,第二个是保留和复制之间的不同。你只需一起回答。我真的想投你的答案,但我没有足够的声誉。谢谢你的工作。 – Michael 2013-03-05 22:43:23

+0

复制会创建一个不同的对象,并拥有自己的保留计数。当您创建一个新对象时,其保留计数为1.当然,复制的对象将位于与原始对象不同的内存区域中。我已经添加了一个例子。 – 2013-03-05 22:55:30

+0

谢谢!这里有一个问题:你没有在dealloc方法中释放someThingNew,你的意思是一些ThingNew应该在其他地方释放? – Michael 2013-03-06 00:21:30