If I’m using a method to return an NSArray, and inside that method I build up the result as a NSMutableArray, I’m often tempted to put return [NSArray arrayWithArray:myMutable] instead of return myMutable just to lock it up and prevent mutation by some devious other code that might check isMemberOfClass on it and do some mutations.
If I’m just coding for myself, and I know I will treat return values as being what they say they are, is there any reason to switch it to NSArray before returning it? Any advantage I’m not seeing here?
There’s no real advantage in doing this; in general you should expect that clients of your interface will respect the contract of that interface.
In the case of many of the Foundation value and container types (
NSString, etc.), it matters even less; due to an implementation detail of the toll-free bridging mechanism, both the mutable and immutable variants are actually instances of the same class. Theinitmethods for NSString and NSMutableString, for example, both actually return an instance of __NSCFString, which inherits from both. This object retains the mutability or immutability of the API you called, but you can’t tell by looking at the class whether it’s mutable or not.In other words,
[aString isKindOfClass:[NSMutableString class]]will always returnYES, regardless of whether you created a mutable object or not. As a result, using that API to check whether something is mutable or not doesn’t work anyway, so there’s no point in worrying whether clients of your API will try to do it.Edit:
I originally stated that you couldn’t tell by inspecting the class of an array whether it was mutable or not, but it turns out that in the case of
NSArray, you can tell. (Thanks to @albertamg for catching the error.) I’ve changed the examples above to useNSString, which is a case where you really can’t tell. In general, though, I would consider it a bug if someone treated an object you returned as mutable when it wasn’t vended as such, and wouldn’t worry about programming around it.Edit again:
So it turns out that in some versions of OS X and iOS, you can’t detect mutablility of
NSArrayeither, but in more recent versions, they’ve changed the implementation such that you can. You still can’t detect it inNSString, though. The lesson to take home from all of this, then, is that you shouldn’t be usingisKindOfClass:on objects that are part of a class cluster.