Re: Determining whether a dictionary is mutable or not
Re: Determining whether a dictionary is mutable or not
- Subject: Re: Determining whether a dictionary is mutable or not
- From: Ken Thomases <email@hidden>
- Date: Sat, 15 Jan 2011 06:04:18 -0600
On Jan 15, 2011, at 5:38 AM, Tito Ciuro wrote:
> On Jan 15, 2011, at 7:36 AM, Ken Ferry wrote:
>
>> I'm not sure this has been made clear: It is intentional that it is difficult to determine whether a dictionary is mutable.
>>
>> That's because you shouldn't do it. Whether a dictionary is mutable _to_you_ is a matter of what's in the header for the method you obtained it from.
>>
>> Suppose that some object keeps a mutable array as its internal state. It also has an accessor that lets you look at the array as an immutable array. If you introspect it and realize its mutable, is it safe to mutate? No! It's part of the object's internal state, you cannot just mess with it.
>>
>> It is unsafe in general to introspect mutability.
>>
>> -Ken
>> Cocoa Frameworks
>
> It makes sense what you're saying because introspecting an object bypassing its accessors would break encapsulation. From the client's perspective this is very clear: use the methods provided and don't mess with the internals. Roger that.
>
> However, how about the other way around? Say you have the same class you mentioned. Internally, it has a mutable array which one can manipulate via dedicated accessors. This object has an init method which accepts an array as input. The client is (should?) be free to pass an immutable or mutable array with values. I see at least two ways to honor this input and initialize the object:
>
> 1) add the input objects to the internal array (i.e. - (void)addObjectsFromArray:(NSArray *)otherArray)
> 2) assign the mutable version of the input array to the internal array (i.e. internalArray = [theInputArray mutableCopy])
>
> In case of #2, (perhaps mistakenly) I was attempting to check whether it was necessary to mutate an already mutable array. It just seemed like the right thing to do: figure out whether the input array is mutable, if it isn't then make it mutable. Then proceed to set the array as the object's contents. However, since this init process is called once, perhaps it just makes sense to always call mutableCopy and be done regardless of the input type. Would this be the right approach perhaps?
>
> My main concern is how to deal with this mutability/non-mutability from the inside, not the outside.
You should copy any state which you need to be private.
What if the code which calls your init method had, in fact, passed a mutable array? Why in the world would you want to make that your internal state? That would mean that your internal state is open to manipulation from the outside. The caller could, after the new object is initialized, modify its (the caller's) mutable array. They have thus unwittingly modified the internal state of the new object.
And, again, if you had declared your initializer to take an immutable object as its parameter, why would you imagine that the caller would be OK with you mutating it?
Sharing state is always fraught with difficulties. When it comes to value objects, including collections, you should default to making copies. Only retain them (and thus share state with the provider) after careful consideration of the close coupling that would result. And even then, it makes little sense to have the behavior be conditional on the object's mutability.
I'll also point out that code which tries to determine the mutability and then takes one of two different paths is more complex and error-prone than code which just does one straightforward thing.
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