Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
719 views
in Technique[技术] by (71.8m points)

objective c - iPhone memory management (with specific examples/questions)

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

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

1 Reply

0 votes
by (71.8m points)

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. :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...