views:

126

answers:

3

Hey there,

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

+1  A: 

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.

Pablo Santa Cruz
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.
Abizern
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?
Ward
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.
Yar
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.
Peter Hosey
That's right. Thanks Peter.
Pablo Santa Cruz
@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;`
Abizern
Abizern: See the edit list for this answer. The final paragraph in the previous version is what Ward was asking about.
Peter Hosey
+2  A: 

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.

Eimantas
+3  A: 

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];
}
Brandon Bodnár
thanks - as a follow-up does the same apply to dictionaries?
Ward
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.
Brandon Bodnár
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 http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html and http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/AccessorConventions.html .
Peter Hosey
@Peter. Of Course. No idea what I was thinking on that. Too much java work recently. Fixing it now.
Brandon Bodnár