In addition to what mmalc pointed you to, there are other red flags in your 
description:

On Jan 14, 2010, at 5:11 PM, Carter R. Harrison wrote:

> My model is an NSMutableSet that contains NSMutableDictionaries.

I think this is asking for trouble.  A set of mutable dictionaries doesn't make 
much sense.

One of the defining characteristics of a set is that it can't have two equal 
objects in it at once.  However, mutable dictionaries can change whether they 
are equal when you mutate them.  "Equal" is determined by the -isEqual: and 
-hash methods, not by identity (memory location).

Sets are not implemented to a) be aware of when the contained objects change or 
b) cope with the change.

Quite aside from the question of whether two dictionaries become equal after 
being added to the set is the fact that they will change their hash value when 
mutated.  While the implementation of NSSet is private, it almost certainly 
depends on the hash value of the contained objects.  So, if you put a 
dictionary into the set, mutate it, and then ask the set if it contains the 
dictionary, it may very well say that it does not.  That's because its internal 
bookkeeping used the original hash to file the dictionary in its data 
structures, but uses the new hash to try to look it up.

The NSSet documentation says:

"Note that if mutable objects are stored in a set, either the hash method of 
the objects shouldn’t depend on the internal state of the mutable objects or 
the mutable objects shouldn’t be modified while they’re in the set (note that 
it can be difficult to know whether or not a given object is in a collection)."

A similar warning in the description of -[NSObject hash] specifically uses a 
mutable dictionary as an example of a mutable object which may change its hash 
when mutated.

I recommend using immutable dictionaries or instances of a custom class with 
proper properties and with semantics for -isEqual: and -hash that aren't 
affected by modifications to those properties.  The default semantics provided 
by NSObject, which is that equality is the same as object identity, are 
appropriate in the most common circumstances.  (It depends on whether your 
custom class is a "value object" or not.)


> I then have a NSTableView with several columns.  I want each column in the 
> table to display a value from each NSMutableDictionary.

NSArrayController is only documented as handling sets in the case when managing 
a relationship of a managed object.  I have no idea if it works in the general 
case.  I wouldn't bet on it.

Since a table view is an inherently ordered construct, I'd strongly recommend 
that you use an indexed collection (e.g. array) for your model.


> //This method is here for testing.  A button in the UI is connected to the 
> method.
> //When executed this method creates a new NSMutableDictionary.  Adds some 
> key/value
> //pairs to it then adds the NSMutableDictionary to the NSMutableSet (myset).
> - (IBAction)addValueToSet:(id)sender;

> - (IBAction)addValueToSet:(id)sender
> {
>       NSString *newString = @"New Value";
>       NSMutableDictionary *dict = [[[NSMutableDictionary alloc] 
> initWithCapacity:1] autorelease];
>       [dict setValue:newString forKey:@"Caption"];
>       [myset addObject:dict];
> }

This illustrates my concern about using a set.  In addition to the fact 
(alluded to by mmalc) that you're not mutating the set in a KVO-compliant 
manner, all of the dictionaries added by this method are equal.  Therefore, 
there's no reason to believe that myset is actually being changed by the 
-addObject: message.  If it already contains an equivalent dictionary, then 
-addObject: would do nothing. 

Regards,
Ken

_______________________________________________

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