释放财产(Objective-C)

时间:2009-05-09 13:32:56

标签: objective-c iphone

我有一个@property,其定义如下:

@property(非原子,保留)名称;

在一个函数中,我解析了一些xml并设置了name属性。 我的问题是我应该在保留新的实例之前明确地释放先前保留的实例吗?

例如:

myObj.name = [otherObj getName]; //保留计数+1

...

myObj.name = [otherObj getName]; //这是名称的新实例,是之前发布的名称吗?

2 个答案:

答案 0 :(得分:4)

在一个合成属性设置器中,代码大致类似于此(我们将name作为属性名称,_name将是它引用的实例变量):< / p>

- (void) setName: (NSString *) newValue
{
  if ( newValue == _name )
    return;

  [newValue retain];
  [_name release];
  _name = newValue;
}

现在,它显示了基于您上面的属性声明会发生什么。根据该属性的其他可能属性,该函数将使用[newValue copy]而不是[newValue retain](如果指定了'copy'属性),或者它将全部包含在{{1}中} block(如果'nonatomic'属性 NOT 提供)。

我还应该注意,由于你的属性引用了NSString,它实现了NSCopying协议,你应该真的使用copy而不是retain,即:

@synchronized(self)

这将导致合成的setter使用@property (nonatomic, copy) NSString * name; 而不是-copy,这在您实际传递NSMutableString对象时更安全。不可变字符串最终只会被-retain调用保留,而可变字符串会创建一个新的不可变副本。如果不这样做意味着字符串本身可以在传递给setter之后更改,在没有对象知识的情况下更改值。

答案 1 :(得分:3)

如果您已经合成了属性的访问器(使用@synthesize指令),那么当重新分配属性时,它们将负责释放支持该属性的ivar。您可能希望显式释放ivar的唯一时间是您的对象被取消分配。所以,你的dealloc方法可能如下所示:

- (void)dealloc {
  [name release];
  // other cleanup here
  [super dealloc];
}