Reputation: 9432
This is a question that's been bothering me for a while.
I want to send some data in an NSArray to a viewController, and sometimes I need to create a NSMutableArray and populate it element by element.
If I send it to the viewController, it will be useless, as it only needs to read the array. So I'm wondering if it's more expensive to send an NSMutableArray, or to create a (maybe?) more lightweight NSArray, with the cost of memory allocation, and releasing the (maybe?) heavier NSMutableArray.
By the way, I know it's over optimization, but I'm curious.
Upvotes: 3
Views: 368
Reputation: 11335
NSArray and NSMutableArray are both implemented with CFArray's so they should have the same performance at accessing element, if you took a look at the open-source-version but the closed-source you are using may differ (see comments).
The performance difference of using NSArray vs NSMutable array arises primarily when you copy the array. if you send -copy to an immutable array, it just bumps the retain count, but sending -copy to a mutable array will allocate heap memory.
Upvotes: 2
Reputation: 162712
(Or, very very little and only in uncommon cases)
It has everything to do with how defensive you want your code to be.
You can always return a subclass of whatever a method declares it's return type to be. That just works.
The caller will only see it as a whatever the superclass is (NSArray
in this case), unless they do something exceptionally dangerous by down casting to NSMutableArray
and mutating the array.
When this happens, if you are still using that array as a backing store in your object, the caller will effectively be modifying your backing store out from under you.
By return [[mutArray copy] autorelease];
you are ensuring that such silliness can never happen. And, in fact, the AppKit suffered enough bugs from people casting and mucking with the arrays, that various methods have moved to return [[mutArray copy] autorelease];
There is also a threading implication; read-only Foundation types are generally thread safe. Read-write are not and that includes reading while something else is writing. Thus, if you return a reference to a mutable array, you cannot modify that array from another thread ever again unless you absolutely know that all external references are gone (which, btw, isn't knowable without poor design).
The performance implication of immutable vs. mutable on copy is only very rarely an issue.
Upvotes: 6
Reputation: 77191
You can build it as an NSMutableArray but then send it as an NSArray. This is valid, note the return type is NSArray but the object is NSMutableArray. You can do this because a NSMutableArray is a NSArray, it is a subclass of NSArray. In this example the caller gets an NSArray that they can't* modify.
-(NSArray*)buildArray
{
NSMutableArray* mutArray = [NSMutableArray arrayWithCapacity:50];
... fill the array...
return mutArray;
}
*not without casting
Upvotes: 3
Reputation: 8357
If you are never going to use that particular array again, I would declare the return value to be an NSArray
and just return the NSMutableArray
you've just used to build it.
If you might use that array internally or return it later, I'd use [NSArray arrayWithArray:mutableArray]
to "downgrade" it. Especially if you are creating a framework that others will be using.
Upvotes: 0