On Jan 15, 2011, at 1:04 PM, Ken Thomases wrote:

> 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

Ken, looks like I wasn't clear enough. In general (not only in this case) I 
would not retain the array unless it was immutable. Otherwise, as you well 
point out, retaining a mutable one  would allow external clients manipulate the 
array bypassing the accessors provided, thus breaking encapsulation.

I understand that my original approach was flawed because I really don't need 
(nor should I care) about the original state of the collection being passed: 
since the class allows the data to be manipulated via accessors, the inited 
data, if provided, should be copied internally regardless of the array state 
being passed. That would make a private copy of the data only accessible via 
the class accessors.

I was looking for a solution where there was not a problem.

Best regards,

-- Tito
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to