views:

216

answers:

2

I have a @property which is defined like this :

@property (nonatomic, retain) name;

In a function I parse some xml and set the name property. My question is should I explicitly release previous retained instance before retain a new one ?

For exemple :

myObj.name = [otherObj getName]; // retain count +1

..

myObj.name = [otherObj getName]; // which is a new instance of a name, is the previous name released ?

+2  A: 

If you have synthesized the accessors for your property (with the @synthesize directive), they will take care of releasing the ivar that is backing the property when the property gets reassigned. The only time you might want to explicitly release the ivar is when your object gets deallocated. So, your dealloc method might look like this:

- (void)dealloc {
  [name release];
  // other cleanup here
  [super dealloc];
}
Jason Coco
Basically, properties are just shorthand for calling getters and setters. Whatever happens in your setter will happen when you set the property. In the synthesized setter for retain and copy properties, it will release the old object and retain (or copy) the new one.
Chuck
@chuck Yes, I know. It's why I specified that the property is managed as long as it's synthesized.
Jason Coco
+4  A: 

In a synthesized property setter, the code does something roughly analogous to this (we'll have name be the property name, and _name will be the instance variable to which it refers):

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

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

Now, that shows what would happen based on your property declaration above. Depending on the other possible attributes of that property, that function would either use [newValue copy] instead of [newValue retain] (if the 'copy' attribute was specified), or it would all be wrapped in an @synchronized(self) block (if the 'nonatomic' attribute was NOT supplied).

I should also note that since your property refers to an NSString, which implements the NSCopying protocol, you should really be using copy rather than retain, i.e.:

@property (nonatomic, copy) NSString * name;

That will cause the synthesized setter to use -copy instead of -retain, which is safer when you're actually passed an NSMutableString object. An immutable string would ultimately only get retained by the -copy call, while a mutable string would create a new immutable copy. Failing to do that means that the string itself could be changed after it's been passed into the setter, changing the value without your object's knowledge.

Jim Dovey
Even if you want to be able to change an NSMutableString, you would need to override the synthesized setter with one that performs a mutableCopy on the new value. That way the original is safe, and you can change your copy of the string if you need/want to.
Abizern
Yep, and you'd define your property as an NSMutableString as well. Also worth pointing out: you can't check whether an NSString is really an NSMutableString using <code>[str isKindOfClass: [NSMutableString class]]</code>, because NSString is a 'class cluster', meaning you actually get an instance of an NSString *subclass*, which happens to also be an NSMutableString subclass. Your best bet is to use <code>-mutableCopy</code>, which will retain if the receiver is already mutable.
Jim Dovey