When returning an NSArray
(or NSDictionary
, etc.) from a method that builds the array on the fly using an NSMutableArray
, what is the standard way to do this and avoid random memory leaks when using ARC?
For example, let's say we had some class with a list of names, and we wanted to manually filter and grab all of the names that started with a given letter:
- (NSArray *)getNamesByFirstLetter:(NSString *)firstLetter
{
NSMutableArray *returnValue = [[NSMutableArray alloc] init];
for(id item in self.names)
{
if([item hasPrefix:firstLetter])
{
[returnValue addObject:item];
}
}
return returnValue; // just return the above array
}
When it comes to returning the value, I can think of four possible ways to do it:
Return the NSMutableArray
directly (as above)
return returnValue;
Return a copy
return [returnValue copy];
Return using NSArray arrayWithArray
:
return [NSArray arrayWithArray:returnValue];
Create an NSArray
, manually set the NSMutableArray
to nil
:
NSArray *temp = [NSArray arrayWithArray:returnValue]; // could use [returnValue copy] here too
returnValue = nil;
return temp;
When a program is using ARC, is there any real difference between these four methods, or does it just come down to personal preference?
Also, besides possible memory leaks, are there any other implications when using one method over another?
Note, if this is a duplicate, let me know, and I'll take the question down. I tried searching, but had a hard time trying to condense the issue down to a few search terms.
The primary difference between NSArray and NSMutableArray is that a mutable array can be changed/modified after it has been allocated and initialized, whereas an immutable array, NSArray , cannot.
An object representing a static ordered collection, for use instead of an Array constant in cases that require reference semantics.
Objective-C programming language does not allow to return an entire array as an argument to a function. However, you can return a pointer to an array by specifying the array's name without an index.
You can reverse a NSArray by writing your own loop iterating from the end towards the beginning and using a second array to add the items in reverse order. Or you can simply use - (NSEnumerator *)reverseObjectEnumerator from the NSArray class.
All four of your options are fine with ARC enabled (i.e. none of your proposed solutions will cause a memory leak).
However, the 4 solutions you outline do slightly different things. Number 1 will return an NSMutableArray
, which likely won't cause problems because NSMutableArray
will respond to all the same messages as NSArray
(but the returned object will be mutable, which you might not want).
There is a subtle difference between option 2 and options 3 & 4 (which are identical under ARC). If returnValue
is nil
, option 2 will return nil
, but options 3 & 4 will return an empty NSArray
. (Either behavior might be desirable; you should decide how you want this method to behave). Also, -copy
is likely a faster operation than +arrayWithArray
.
I would go with option 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With