Duy Pham
Duy Pham

Reputation: 35

NSMutableDictionary does not work properly

Currently I have a very strange problem using NSMutableDictionary: same code, same data but different results of key-value pairs objects.

My dictionary uses an user-defined class objects as keys and values are array of objects.

Here is the code to build dictionary:

_designs = [[NSMutableDictionary alloc] init];
for (Hierarchy * hier in downloadedHierarchies.objects)
{
    NSLog(@"Hierarchy [%d - %d - %@]", hier.designId, hier.hierarchyId, hier.hierarchyName);
    Design * aDesign = [[Design alloc] initWithId:hier.designId withName:hier.designName];

    NSMutableArray *array = ([_designs objectForKey:aDesign] == nil) ? [[NSMutableArray alloc] init] : (NSMutableArray *)[_designs objectForKey:aDesign];
    NSLog(@"Design %d has %d of hierarchies", aDesign.designId, array.count);

    [array addObject:hier];

    [_designs setObject:array forKey:aDesign];
    NSLog(@"Design %d now has %d of hierarchies", aDesign.designId, [[_designs objectForKey:aDesign] count]);
}

Problem is: - My test data has only 1 design and 3 hierarchies. Each time I run the application, I get different results in my dictionary. Sometimes I get 2 key-value pairs, sometimes 3. Even keys are from the same design (same designId), and hierarchies are scattered among those key-value pairs.

Some notes:

What have I done wrong here ?

Upvotes: 0

Views: 126

Answers (1)

David Hoerl
David Hoerl

Reputation: 41622

You need to also provide isEqual and hash in your Design object. This is taken from NSObject's Protocol description:

isEqual: Returns a Boolean value that indicates whether the receiver and a given object are equal. (required)

  • (BOOL)isEqual:(id)anObject Parameters anObject The object to be compared to the receiver. Return Value YES if the receiver and anObject are equal, otherwise NO.

Discussion This method defines what it means for instances to be equal. For example, a container object might define two containers as equal if their corresponding objects all respond YES to an isEqual: request. See the NSData, NSDictionary, NSArray, and NSString class specifications for examples of the use of this method.

If two objects are equal, they must have the same hash value. This last point is particularly important if you define isEqual: in a subclass and intend to put instances of that subclass into a collection. Make sure you also define hash in your subclass.

Upvotes: 0

Related Questions