views:

100

answers:

3

Which variant is more correctly?

//first variant
    - (NSArray*) someArray
    {
     NSMutableArray* mutArr = [[NSMutableArray alloc] init];

     //...some operations with mutArr


     NSArray* retArray = [mutArr copy];

     [mutArr release]; //remove mutArr

     return [retArray autorelease];
    }

//second variant
    - (NSArray*) someArray
    {
     NSMutableArray* mutArr = [[NSMutableArray alloc] init];

     //...some operations with mutArr 

     return (NSArray*)[mutArr autorelease];
    }
+1  A: 

The first one is better, in my opinion. It ensures immutability.

dreamlax
But is it important to ensure immutability in this case? Since the array in question is a temporary working variable, why bother making a copy?
benzado
We don't know where the array is going or how it is handled. Even though the return type indicates `NSArray`. An object serialiser for example, goes off what the object's actual class is, not the type of variable you told the compiler it would be.
dreamlax
That depends on the serializer; Cocoa's NSKeyedArchiver stores all arrays as immutable. If you archive a mutable array, you'll get an immutable array when you unarchive. You need to call `mutableCopy` in your `initWithCoder:` if you need a mutable array.
benzado
+1  A: 

I'm assuming that you mean for mutArr and names to be the same array. If that's the case, then the first is more correct, since you don't really need to make a copy of it.

You can just return mutArray if you want; since NSMutableArray is a subclass of NSArray, returning one will work. If you want to return a regular, non-mutable NSArray, I would recommend the following:

(NSArray*)someArray {
    NSMutableArray* mutArr = [[[NSMutableArray alloc] init ] autorelease];
    // your operations here
    return [NSArray arrayWithArray:mutArr];
}
Jeff Kelley
Don't forget to release `mutArr` before returning, or `autorelease` it at least.
dreamlax
Whoops, good catch. Fixed.
Jeff Kelley
Yes of course. It was my error. mutAttr and names are the same array. I have fixed it.
+4  A: 

The answer is, how much of a problem will there be if the array is changed after you return it?

If you are creating a mutable array inside your method then returning it, never to use it again, I think it is fine to return the mutable version. The fact that your method declares a return type of NSArray only means you won't guarantee the array will be mutable. You don't have to guarantee that it is immutable.

On the other hand, if you are returning an array that your class uses internally, it is much safer to return an immutable copy. In your example above, that does not appear to be the case.

The consumer of the array, should they want to keep a reference, should use copy instead of retain; if the array is mutable, they will get an immutable copy. If it is already immutable, only the reference count will be increased. So there's no penalty for copying an immutable object.

In other words, your second variant is fine. (Although the cast to (NSArray *) is totally unnecessary.)

benzado