Okay, here's the deal.
When you define a property like so...
@property (nonAtomic, retain) NSString myName;
...because of the defaults of the property command its actually like defining it as:
@property (nonAtomic, readwrite, retain, getter=getMyName,setter=setMyName) NSString myName;
When you use @synthesize myName;
behind the scenes, the complier generates a getter method that looks something like this:
-(void) setMyName:(NSString *) aString{
if (!(myString==aString) { //test if a string is the same **object** as the current myString
if (aString != nil) { // if nil we don't want to send a retain
[aString retain]; // increment the retain count by one
}
[myString release]; //decrement the retain count of the currently assigned string by one.
myString=nil; //set the pointer to nil to ensure we don't point to the old string object
myString=aString; //assign the newly retained object to the myString symbol
}
}
As you can see, any string from any source, of any prior retain count, autoreleased or not, will be automatically retained by the method upon assignment and when a new value is assigned, it will be automatically released by the method. Multiple assignments will not stack the retain count. As long as you use the generated setter, the object assigned (in this case aString) will always have a retain count that will keep it alive in the class.
This is why you can do this...
self.myName=[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"]
;
without having to do this:
self.myName=[[NSSting stringWithFormat:@"%@ is correct.", @"TechZen"] retain];
... and not have to worry if the string value will suddenly disappear when the autoreleasepool drains.
However if you ever call...
[self.myName release];
...anywhere outside the dealloc
, then the object in the property my be nilled unless you track it relentlessly. By the same token, if you call..
[self.myName retain];
... anywhere, then the object in the property will leak (possibly even after the self object has been deallocated.)
This is why I say never to retain or autorelease any object assigned or copied in a property. It's not only pointless but counter productive. It follows that you only want to call release on a property when you are done with the self object because the efficient tracking of the retain count by the setter means that you can nil the property even though you may still needed.
Autorelease is never needed for a property because the property is always retained by the self object and any other object should handle retention internally if it uses the self object's property.
Once you understand what goes on inside the generated accessors, the rules are obvious. Never retain a property's object explicitly. Never release a property's object save in dealloc. Never autorelease a property's object.
The obvious corollary to these rules is always to use the self.propertyName references internally in the self object to ensure that the retention of the property's is automatically managed.