开发者

Is it important / good to convert mutables to immutables before returning them?

If I'm using a method to return an NSArray,开发者_JAVA技巧 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. The init methods 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 return YES, 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 use NSString, 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 NSArray either, but in more recent versions, they've changed the implementation such that you can. You still can't detect it in NSString, though. The lesson to take home from all of this, then, is that you shouldn't be using isKindOfClass: on objects that are part of a class cluster.


I've been writing a category for NSArray which contains purely functional methods and returning immutable objects based on the original array is a must. But I wouldn't bother in any other context. Maybe as an idiot-proofing measure in a Framework for public consumption.

If you're trying to mutate the immutable somewhere in your code path you probably have a problem that shouldn't be rectified by 'putting down the barrier' so to speak.


Not really, if you are writing a library and you want to protect the array from begin changed of cause it is a good idea, it depends on how closely connect the two parts of code are, returning a NSArray instead of a NSMutableArray is a good practice for catching possible errors, but of cause creating a new array takes CPU cycles, you have to basically make the call yourself based on the situation, I tend to like to take it safe in situation like this, I will often add NSParameterAsserts in my code just to catch possible logic problems as soon as I can, with objective-c being a dynamic language it seems to be a good practice to be careful, about stuff like this. I guess if it is not in code which call in some time critical part I would do as you do.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜