Until yesterday I thought I understood how properties memory management works, but then I ran an “Analize” task with XCode and got plenty of “This object is not own here”. Here is a simple example that describes my problem :
MyObservingObject.h:
@interface MyObservingObject : NSObject
@property(nonatomic, retain) NSMutableDictionary *observedDictionary;
-(id)initWithDictCapacity:(int)capacity;
@end
MyObservingObject.m:
@synthesize observedDictionary;
-(id)initWithDictCapacity:(int)capacity {
self = [super init];
if (self) {
self.observedDictionary = [[[NSMutableDictionary alloc] initWithCapacity:capacity] autorelease];
}
return self;
}
- (void)dealloc {
// The following line makes the Analize action say :
// "Incorrect decrement of the reference count of an object that is not owned at this point by the caller"
[self.observedDictionary release], self.observedDictionary=nil;
[super dealloc];
}
What I don’t understand is Why should I leave this property without calling release on it? My @property is set as retain (copy does the same), so when I’m doing self.myRetainProperty = X, then X got its retain count increased (it’s owned by self), didn’t it ?
It did get increased, but when you set it to
nil, the setter method first releases the backing instance variable, and only then does it retain and assign the new value. Thus setting the property tonilis enough, setting the ivar tonilleaks memory, though.For your better understanding: the typical implementation of an autogenerated retaining setter is equivalent to something like
Also note that, as a consequence, you should never release properties like this. If you do so, the backing ivar may be deallocated, and messaging it (
releaseby the accessor when setting the property tonilafterwards) can crash.