1

SOLVED

It seemed that both -referenceDictionary were not containing exact same information… Dang it ! Fixed it and now it works perfectly.

Initial question

It's been a few hours since I started struggling with this problem, here it is :

I have a CustomClassA which I use as NSDictionary key (obviously for the Object:ForKey: method).

At first it did not work at all, then I read this, that and a few other stuffs around the web…

So I tried overriding both -isEqual: and -hash by doing as said (maybe a little less :p) :

- (BOOL)isEqual:(id)anObject
{
    if([anObject isKindOfClass:[self class]])
    {
        NSLog(@"HASH = %@", [anObject hash] == [self hash] ? @"YES" : @"NO");
        NSLog(@"DICT = %@", [[self referenceDictionary] isEqualToDictionary:[anObject referenceDictionary]] ? @"YES" : @"NO");
        return [[self referenceDictionary] isEqualToDictionary:[anObject referenceDictionary]];
    }
    return false;
}
- (NSUInteger)hash
{
    NSUInteger prime = 31;
    NSUInteger result = 1;
    NSArray* values = [referenceDictionary allValues];
    for(id k in values)
    {
        result = prime * result + [k hash];
    }
    return result;
}

Please, note that my NSDictionary will never contain nil values because I do take care of having these away.

Anyway, both of these methods do return YES on one of the NSDictionary entry when calling :[myDict objectForKey:myObject].

But still, it seems [myDict objectForKey:myObject] returns nil, even after "setting" it myself…

If anyone has time to help me solving my pb I'd be thankful !

Regards, Cehm

EDIT: Ok, for the purpose of being a bit more clear about this issue. Lets assume two classes : Artist and Single.

Then I want to create a NSDictionary which contains an Artist as the key and this Artist key points to a NSArray of "Single"s.

For instance I'd have the following dictionary :

@{
artistA : @[song1, song2, song3],
artistB : @[songZ],
artistC : @[songF]
}

But now the thing is I want to create this dictionary like this :

for(Single* aSong in ArrayOfSingle)
    {
        Artist* anArtist = [[Artist alloc] initWithArtistName:aSong.artistName];
        if([data objectForKey: anArtist] == nil)
        {
            [data setObject:[[NSMutableArray alloc] init] forKey: anArtist];
        } else
        {
            NSLog(@"exists");
        }
        [[data objectForKey: anArtist] addObject:aSong];
    }

Taken into account that data is mutable (Simple NSMutableDictionary) and that I won't ever change anArtist (assuming ARC still keeps its instance…).

EDIT 2:

I overrode NSCopying :

- (id)copyWithZone:(NSZone *)zone {
    return [[[self class] allocWithZone:zone] initWithDictionary:referenceDictionary];
}

As my CustomClass uses initWithDictionary: I assumed it would work just fine by doing this.

EDIT 3:

Here's the initWithDictionary:

-(id) initWithDictionary:(NSDictionary*) dictionary
{
    self = [super initWithDictionary:dictionary];
    if(self)
    {
        referenceDictionary = dictionary;
        title = [super notNullObjectForKey:@"title"];
        name = [super notNullObjectForKey:@"name"];
        category = [super notNullObjectForKey:@"category"];
        artist = [super notNullObjectForKey:@"artist"];
        ad_city = [super notNullObjectForKey:@"ad_city"];
    }
    return self;
}
Community
  • 1
  • 1
Cehm
  • 1,502
  • 1
  • 12
  • 14
  • 2
    I gather that `-referenceDictionary` returns an `NSDictionary` pointer. Further, it seems that that property is the only thing considered for equality. Have you considered making your `-hash` simply return `[referenceDictionary hash]` since your `-isEqual:` simply uses the `NSDictionary` implementation already? Also, have you properly implemented `NSCopying` for your class? Dictionaries copy their keys. Finally, is your class or its `referenceDictionary` mutable? If so, and you mutate it after using it as a dictionary key, then it will no longer match the key stored by the dictionary. – Ken Thomases Apr 23 '14 at 15:14
  • What is the use case of this object as a key? – Wain Apr 23 '14 at 15:17
  • @KenThomases Please check my edits. I just tried using [referenceDictionary hash] in the -hash method, but seems to do the same. referenceDictionary is immutable. – Cehm Apr 23 '14 at 15:31
  • Does `-initWithDictionary:` just copy the input dictionary as-is, or does it tweak it? – Ken Thomases Apr 23 '14 at 23:16
  • @KenThomases Check edit3, I copied a bit of code in order to show you my init method – Cehm Apr 24 '14 at 07:34
  • At this point, I can only recommend that you log `anArtist`, `[anArtist referenceDictionary]`, and iterate over `data` logging each key, each key's `referenceDictionary`, and whether the key equals `anArtist` and the key's `referenceDictionary` equals `anArtist`'s. – Ken Thomases Apr 24 '14 at 15:39

0 Answers0