Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Hey all. I know this question's been asked but I still don't have a clear picture of memory management in Objective-C. I feel like I have a pretty good grasp of it, but I'd still like some correct answers for the following code. I have a series of examples that I'd love for someone(s) to clarify.

Setting a value for an instance variable:

Say I have an NSMutableArray variable. In my class, when I initialize it, do I need to call a retain on it?

Do I do

fooArray = [[[NSMutableArray alloc] init] retain];

or

fooArray = [[NSMutableArray alloc] init];

Does doing [[NSMutableArray alloc] init] already set the retain count to 1, so I wouldn't need to call retain on it? On the other hand, if I called a method that I know returns an autoreleased object, I would for sure have to call retain on it, right? Like so:

fooString = [[NSString stringWithFormat:@"%d items", someInt] retain];

Properties:

I ask about the retain because I'm a bit confused about how @property's automatic setter works.

If I had set fooArray to be a @property with retain set, Objective-C will automatically create the following setter, right?

- (void)setFooArray:(NSMutableArray *)anArray {
    [fooArray release];
    fooArray = [anArray retain];
}

So, if I had code like this: self.fooArray = [[NSMutableArray alloc] init]; (which I believe is valid code), Objective-C creates a setter method that calls retain on the value assigned to fooArray. In this case, will the retain count actually be 2?

Correct way of setting a value of a property:

I know there are questions on this and (possibly) debates, but which is the right way to set a @property?

This?

self.fooArray = [[NSMutableArray alloc] init];

Or this?

NSMutableArray *anArray = [[NSMutableArray alloc] init];
self.fooArray = anArray;
[anArray release];

I'd love to get some clarification on these examples. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
666 views
Welcome To Ask or Share your Answers For Others

1 Answer

According to Apple's Object Ownership Policy, any method that begins with the words alloc or new, or contains copy is owned by the caller.

To obtain ownership of an object, you must retain it.

So, in your first example, the retain is unnecessary because you already own the object.

The correct way to do this:

fooArray = [[NSMutableArray alloc] init];

Since autoreleased objects are owned by the current autorelease pool, you must call retain on them to gain ownership of them, so this example is correct:

fooString = [[NSString stringWithFormat:@"%d items", someInt] retain];

This would work fine as well:

self.fooString = [NSString stringWithFormat:@"%d items", someInt]; //retained by property setter

And for your last example using the property setter, this would be the correct way to do it:

NSMutableArray *anArray = [[NSMutableArray alloc] init];
self.fooArray = anArray;
[anArray release];

Instead of having to do the above, I'd suggest the following solution:

self.fooArray = [NSMutableArray arrayWithCapacity:10];

arrayWithCapacity: will return an autoreleased NSMutableArray, which is the retain-ed by the property setter method. :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...