Reputation: 4731
In the following code, I don't get any warning or compile error if I return NSMutableArray instead of NSArray which is the method's return type.
But is it good practice to convert return value to NSArray by using -copy method like the following code?
Or should I return NSMutableArray?
+(NSArray *)returnImutableArray {
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:@"a"];
[arr addObject:@"b"];
//return arr; // no warning
return [arr copy];
}
Upvotes: 2
Views: 481
Reputation: 104698
I return an immutable copy
of interior mutable instances by default. Not just NSArray
, but several other types.
I don't want mutable objects floating around, although it's not a problem that it mutates as long as you treat it as concrete.
I consider it a better default because it minimizes shallow copying if shared. That is, if you take the result and assign it to one or more objects which are copy
properties, then all those actions must make concrete shallow copies, when they could effectively retain
. This is the same reason you should favor copy
for properties of these types, rather than retain
when declaring properties.
In some cases, you just know its scope is limited and that the mutable won't get out -- in that case, I may not bother making the copy.
Upvotes: 0
Reputation: 1769
This all depends on what you want to achieve with the array.
If you really don't want or need to modify the returned array, return it as an NSArray. You could as well return it as an array, without copying it.
In both cases, don't forget the memory management.
You should never return anything with a retain count >0.
+(NSArray *)returnImutableArray {
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:@"a"];
[arr addObject:@"b"];
NSArray * returnArray = [NSArray arrayWithArray:arr];
[arr release];
//return arr; // no warning
return returnArray;
}
Or you could do so:
+(NSArray *)returnImutableArray {
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:@"a"];
[arr addObject:@"b"];
//return arr; // no warning
return [arr autorelease];
}
There's no need to copy the NSMutableArray as it extends the NSArray so your code will never break if you do so.
Upvotes: 0
Reputation: 21373
I think this is essentially personal preference. You incur a (probably small) performance penalty by copying the array before returning it. The upside is that you'll completely prevent mutation of the result further down the line. However, I don't usually go to the trouble. Because the declared return type of the method is an immutable NSArray, the compiler will warn you if you try to call one of NSMutableArray's mutation methods on it unless you go out of your way to prevent that (by casting to NSMutableArray).
So, in short, it's personal preference and I personally don't generally bother with the immutable copy.
Upvotes: 6