R – Why does this create a memory leak (iPhone)

iphonememory-managementobjective cxcode

//creates memory leak
  self.editMyObject = [[MyObject alloc] init];

//does not create memory leak
  MyObject *temp = [[MyObject alloc] init];
  self.editMyObject = temp;
  [temp release];

The first line of code creates a memory leak, even if you do [self.editMyObject release] in the class's dealloc method. self.editMyObject is of type MyObject. The second line incurs no memory leak. Is the first line just incorrect or is there a way to free the memory?

Best Answer

The correct behavior depends on the declaration of the editMyObject @property. Assuming it is delcared as

@property (retain) id editMyObject; //id may be replaced by a more specific type

or

@property (copy) id editMyObject;

then assignment via self.editMyObject = retains or copies the assigned object. Since [[MyObject alloc] init] returns a retained object, that you as the caller own, you have an extra retain of the MyObject instance and it will therefore leak unless it there is a matching release (as in the second block). I would suggest you read the Memory Management Programming Guide[2].

Your second code block is correct, assuming the property is declared as described above.

p.s. You should not use [self.editMyObject release] in a -dealloc method. You should call [editMyObject release] (assuming the ivar backing the @property is called editMyObject). Calling the accessor (via self.editMyObject is safe for @synthesized accessors, but if an overriden accessor relies on object state (which may not be valid at the calling location in -dealloc or causes other side-effects, you have a bug by calling the accessor.

[2] Object ownership rules in Cocoa are very simple: if you call a method that has alloc, or copy in its signature (or use +[NSObject new] which is basically equivalent to [[NSObject alloc] init]), then you "own" the object that is returned and you must balance your acquisition of ownership with a release. In all other cases, you do not own the object returned from a method. If you want to keep it, you must take ownership with a retain, and later release ownership with a release.

Related Topic