Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning NSMutableArray object from a method with an NSArray return value

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:

  1. Return the NSMutableArray directly (as above)

    return returnValue;
    
  2. Return a copy

    return [returnValue copy];
    
  3. Return using NSArray arrayWithArray:

    return [NSArray arrayWithArray:returnValue];
    
  4. 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.

like image 664
valverij Avatar asked Feb 11 '14 16:02

valverij


People also ask

What is difference between NSArray and NSMutableArray?

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.

What is NSArray Objective-C?

An object representing a static ordered collection, for use instead of an Array constant in cases that require reference semantics.

How do I return an array in Objective-C?

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.

How do you reverse an NSArray?

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.


1 Answers

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.

like image 77
erik Avatar answered Sep 20 '22 19:09

erik