cpjolicoeur
cpjolicoeur

Reputation: 13106

Question on retain attribute with @property and @synthesize

I'm still pretty new to Objective-C coding (as evidenced by this question) and I think I'm not completely understanding how using the retain attribute in a @property declaration works.

Here is an example class:

@interface Foo : NSObject {
    NSMutableArray *myArray; 
}

@property (retain) NSMutableArray *myArray;

My understanding was that adding the retain attribute to the @property declaration (and using the necessary @synthesize delcaration in the implementation file) will basically do the following setter and getter for me:

- (void)setMyArray:(NSMutableArray *)newArray {
    myArray = [[NSMutableArray alloc] initWithArray:newArray];
    [newArray release];
}

- (NSMutableArray *)myArray {
    return myArray;
}

Is this accurate or am I mistaken on how the retain attribute works?

Upvotes: 1

Views: 1284

Answers (3)

Philippe Leybaert
Philippe Leybaert

Reputation: 171864

Adding the retain attribute will actually generate this code:

- (void)setMyArray:(NSMutableArray *)newArray {
    [newArray retain];
    [myArray release];
    myArray = newArray;
}

- (NSMutableArray *)myArray {
    return myArray;
}

The reason the retain method is called on newArray before release on the old value is that if newArray and myArray are the same object, the array will be released before it is retained again.

Upvotes: 5

Georg Schölly
Georg Schölly

Reputation: 126165

It's really hard to do it right. Take a look at the article Memory and thread-safe custom property methods on Cocoa with Love by Matt Gallagher.

Here's one implementation that works, heavily inspired by that excellent article.

- (void)setSomeString:(NSString *)aString {
    @synchronized(self)
    {
        if (someString != aString) // not necessary, but might improve
                                   // performance quite a bit
        {
            [aString retain];
            [someString release];
            someString = aString;
        }
    }
}

- (NSString *)someString {
    @synchronized(self)
    {
        id result = [someString retain];
    }
    return [result autorelease];
}

Upvotes: 1

Mike Weller
Mike Weller

Reputation: 45598

retain will not do a copy of the new value. It will retain the new value and release the old one.

Upvotes: 0

Related Questions