views:

562

answers:

4

I'm still learning about Objective-C memory management. I'm trying to implement several simple classes in an example program that I'm building.

As an example, say I have the following class definition:

 #import <UIKit/UIKit.h>

 @interface customViewController : UIViewController 
 {
    customObject *myCustomObject;
 }

 @property (retain) customObject *myCustomObject;

 - (void)replaceCustomObject:(customObject *)newObject;

 @end

For the property, I use the standard synthesize keyword...

@synthesize myCustomObject;

Then please assume that in the instance of customViewController the myCustomObject is already set with a valid value and is in use. Then the method replaceCustomObject is defined as:

 - (void)replaceCustomObject:(customObject *)newObject
 {
     //Does this cause a memory leak because I just assign over
     //the existing property? 
     self.myCustomObject = newObject;
 }

As the comment asks, does this leak memory? Or is this the valid way to replace a previous object with a new object?

Thank you,
Frank

+2  A: 

That's perfectly valid, and does not leak memory. The synthesized accessors manage retain counts correctly.

(As an aside, you don't need that replaceCustomObject: method; since your property is readwrite by default, you have an auto-generated setCustomObject: method that clients of your class can use, and which follows the normal Cocoa naming conventions.)

smorgan
I know I don't need the replaceCustomObject: method. That was just a way for me to illustrate my overall goal. As you can imagine, where I'm using this is much more than just assigning a property. :-) Thank you for answering my question.
Frank V
+1  A: 

the property accessor syntax

self.x = y;

has the same effect as calling the setter method explicitly:

[self setX:y];

The accessor method will do whatever it has been written to do. In your case, for a @property(retain) property that has been @synthesized, the accessor will release the old object and retain the new one.

So, calling the setter, whether explicitly or through the '.' syntax, will do the right thing - including the right memory management.

So in short: no, this will not leak memory.

Christian Brunschen
+2  A: 

According to this, if you use (retain) in your declaration, the synthesized method will release the old value first, then retain the new one:

if (property != newValue) {
    [property release];
    property = [newValue retain];
}
JW
+2  A: 

As others have mentioned, your code is perfectly valid and won't leak memory when assigning to the property.

If you have forgotten to implement a proper dealloc method, the last object assigned will be leaked when your customViewController is destroyed. A proper dealloc implementation would look like so:

- (void)dealloc
{
    self.myCustomObject = nil;
    [super dealloc];
}
rpetrich
Can you explain further? I've never seen setting a property to nil. Is this equal to doing [self.myCustomObject release] ? This is how I learend to take care of this in the dealloc method...
Frank V
Sending [self.myCustomObject release] is dangerous because after doing so, self.myCustomObject still points to the now-released object! In the dealloc method it is probably safe since self is being destroyed anyway, but I dislike having special rules to remember. To be safe, you could also do the following instead: [myCustomObject release]; myCustomObject = nil;
rpetrich