Re: Mutating message sent to immutable object
Re: Mutating message sent to immutable object
- Subject: Re: Mutating message sent to immutable object
- From: Ken Thomases <email@hidden>
- Date: Sat, 31 Aug 2013 21:25:57 -0500
On Aug 31, 2013, at 9:10 PM, Gerriet M. Denkmann wrote:
> NSUserDefaults tells me about dictionaryForKey: "The returned dictionary and its contents are immutable, even if the values you originally set were mutable."
>
> Does this really mean: "The returned dictionary and its contents are mutable or immutable depending on our whims. You better not rely on their mutability state."
That's _always_ what it means when an API gives you an immutable object. It means the design contract is that you're not allowed to mutate it. It doesn't mean the object is inherently immutable. A class may have a property that returns an immutable NSString but it may simply return a reference to an NSMutableString instance variable. The object is mutable for internal implementation reasons.
From <https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ObjectMutability/ObjectMutability.html#//apple_ref/doc/uid/TP40010810-CH5-SW66>:
> Use Return Type, Not Introspection
>
> To determine whether it can change a received object, the receiver of a message must rely on the formal type of the return value. If it receives, for example, an array object typed as immutable, it should not attempt to mutate it. It is not an acceptable programming practice to determine if an object is mutable based on its class membership—for example:
>
> if ( [anArray isKindOfClass:[NSMutableArray class]] ) {
> // add, remove objects from anArray
> }
> For reasons related to implementation, what isKindOfClass: returns in this case may not be accurate. But for reasons other than this, you should not make assumptions about whether an object is mutable based on class membership. Your decision should be guided solely by what the signature of the method vending the object says about its mutability. If you are not sure whether an object is mutable or immutable, assume it’s immutable.
>
> A couple of examples might help clarify why this guideline is important:
>
> • You read a property list from a file. When the Foundation framework processes the list, it notices that various subsets of the property list are identical, so it creates a set of objects that it shares among all those subsets. Afterward you look at the created property list objects and decide to mutate one subset. Suddenly, and without being aware of it, you’ve changed the tree in multiple places.
>
> • You ask NSView for its subviews (with the subviews method) and it returns an object that is declared to be an NSArray but which could be an NSMutableArray internally. Then you pass that array to some other code that, through introspection, determines it to be mutable and changes it. By changing this array, the code is mutating internal data structures of the NSView class.
>
> So don’t make an assumption about object mutability based on what introspection tells you about an object. Treat objects as mutable or not based on what you are handed at the API boundaries (that is, based on the return type). If you need to unambiguously mark an object as mutable or immutable when you pass it to clients, pass that information as a flag along with the object.
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden