4

I never seem to get this right. I've got a method that returns a mutable array. What is the proper way to return the array and avoid potential memory leaks?

If I plan to store the results locally inside another view controller, does that affect the way the array should be returned?

Lastly, what if it's just an non-mutable array? Does that require a different technique?

thanks, Howie

3
  • The whole point of all these great answers is that, from the calling method, if you don't alloc you don't have to release meaning that it MUST be autoreleased. Wanted to leave this link too developer.apple.com/mac/library/documentation/cocoa/Conceptual/… Commented Mar 21, 2010 at 19:21
  • yar: That's a bit misleading, as it implies that you have to autorelease it, but autoreleasing is effectively the same as releasing (since that's what it does, just not immediately). What you meant is that an object created by a method without alloc, new, or copy in its selector is already autoreleased, so you can just return that. Commented Mar 21, 2010 at 19:41
  • @Peter Hosey, that is what I meant, did NOT mean to imply you would have to autorelease it yourself. I meant that the called method... well, you know what I meant, your comment is clearer :) Commented Mar 21, 2010 at 22:52

3 Answers 3

4

If your method does not have alloc or copy in the name then the proper thing is to return a autoreleased version of the array. Also, you should return a copy of the array to prevent modifications to your local copy

- (NSMutabalArray*] mutableArray {
    return [[myArray mutableCopy] autorelease];
}

- (NSArray*] array {
    return [[myArray copy] autorelease];
}
Sign up to request clarification or add additional context in comments.

3 Comments

Yes. It is normally true for any container class that your should return either a copy of mutableCopy of it, if you need prevent changes made to the returned copy from affecting the instance you have inside your class. Granted the copying mechanism is not need if the container is created inside the method solely for returning, in this case you don't need to worry about the copy.
I'll point out for other readers that you normally should not name a method getFoo, as the “get” prefix in Cocoa style indicates a method that returns a value by reference (as NSColor's getRed:green:blue:alpha:, which takes four pointers to CGColor variables into which you want it to put the component values). See developer.apple.com/mac/library/documentation/Cocoa/Conceptual/… and developer.apple.com/mac/library/documentation/Cocoa/Conceptual/… .
@Peter. Of Course. No idea what I was thinking on that. Too much java work recently. Fixing it now.
2

Return an auto-released object. If you've created your array with any alloc/init/copy methods - you should send autorelease message to array before returning it (something like return [myArray autorelease];). Otherwise arrays created with factory methods (arrayFrom... arrayWithContentsOf...) return autoreleased object so you don't need to worry about memory leaks there.

You should read about memory management and retain count on apple dev site. There might be some other initialization methods that retain returned object which would 'cause a memory leak.

Comments

1

For a NSMutableArray I would use:

-(NSMutableArray*)getMyArray
{
   NSMutableArray *retval = [[NSMutableArray alloc] init];
   // do your stuff w/ array
   return [retval autorelease];
}

The caller of this code may want to retain the returned array, since it is autoreleased.

6 Comments

As an NSMutableArray* is being returned, I'd recommend calling copy on the the returned object unless you want the array to be able to changed underneath you.
thanks - what is the difference if I retain the returned array or dont retain it? It is just a matter of what I intend to do with it so that if I might need it later I should retain it?
You only need to retain it if you want to hold on to it once the calling method ends. Otherwise, you have the autoreleased object until your method exits.
I've clarified the final paragraph, as the previous version implied (to me, at least) that getMyArray might want to retain it. This method should not; its caller may want to, and I think that's what Pablo meant.
@Ward: If you retain it and the array changes (becuase it's mutable) then the version you've retained also changes (it's just a pointer, after all) This means that you could have a property changing without you knowing about it. That's fine if you want it to do that. But sometimes you just want a copy of the array as it was at the time that you answered it, so a copy might be a better choice. This is the same reasoning behind declaring array properties as @property (copy) NSArray *anArray;
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.