About -(NSDictionary)dictionaryWithObjectsAndKeys: and

34,905

Solution 1

[NSDictionary dictionaryWithObjectsAndKeys: stops to add objects when it finds a nil value.

So most likely one of the objects you try to add in the first code is nil.

Solution 2

The something similar to the code below solved my problem with the same exception:

(NSMutableDictionary *)dictionary {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
                          self.userID, @"id",
                          self.userName, @"name",
                          self.userSurname, @"sName",
                          self.userNickname, @"nName",
                          self.userPassword, @"pwd",
                          [NSNumber numberWithDouble:[self.userBirthday timeIntervalSince1970] * 1000], @"birthday",
                          self.userSex, @"sex",
                          self.userEmail, @"email",
                          self.userLanguage, @"locale",
                          [NSNumber numberWithLongLong:self.userCoin], @"coin",
                          self.userRate, @"rate",
                          [NSNumber numberWithDouble:self.userCoordinate.latitude], @"lat",
                          [NSNumber numberWithDouble:self.userCoordinate.longitude], @"lon",
                          self.userPlaces, @"userPlaces",
                          nil];
}
Share:
34,905
Gabriele
Author by

Gabriele

Updated on July 29, 2020

Comments

  • Gabriele
    Gabriele over 3 years

    I got a really interesting question.

    Inside one of my classes I declared a very simple instance method -(NSDictionary)dictionary; that is implemented in this way:

    - (NSDictionary *)dictionary {
        return [NSDictionary dictionaryWithObjectsAndKeys:
                                  self.userID, @"id",
                                  self.userName, @"name",
                                  self.userSurname, @"sName",
                                  self.userNickname, @"nName",
                                  self.userPassword, @"pwd",
                                  [NSNumber numberWithDouble:[self.userBirthday timeIntervalSince1970] * 1000], @"birthday",
                                  self.userSex, @"sex",
                                  self.userEmail, @"email",
                                  self.userLanguage, @"locale",
                                  [NSNumber numberWithLongLong:self.userCoin], @"coin",
                                  self.userRate, @"rate",
                                  [NSNumber numberWithDouble:self.userCoordinate.latitude], @"lat",
                                  [NSNumber numberWithDouble:self.userCoordinate.longitude], @"lon",
                                  self.userPlaces, @"userPlaces",
                                  nil];
        }
    

    with this method declared there are no @"userPlaces" key inside my return dictionary (self.userPlace is obviously valorized and full of objects).

    So I changed a little bit my method like this:

    - (NSDictionary *)dictionary {      
        NSMutableDictionary *toReturn = [NSMutableDictionary dictionary];
        [toReturn setValue:self.userID forKey:@"id"];
        [toReturn setValue:self.userName forKey:@"name"];
        [toReturn setValue:self.userSurname forKey:@"sName"];
        [toReturn setValue:self.userNickname forKey:@"nName"];
        [toReturn setValue:self.userPassword forKey:@"pwd"];
        [toReturn setValue:[NSNumber numberWithDouble:[self.userBirthday timeIntervalSince1970] * 1000] forKey:@"birthday"];
        [toReturn setValue:self.userSex forKey:@"sex"];
        [toReturn setValue:self.userEmail forKey:@"email"];
        [toReturn setValue:self.userLanguage forKey:@"locale"];
        [toReturn setValue:[NSNumber numberWithLongLong:self.userCoin] forKey:@"coin"];
        [toReturn setValue:self.userRate forKey:@"rate"];
        [toReturn setValue:[NSNumber numberWithDouble:self.userCoordinate.latitude] forKey:@"lat"];
        [toReturn setValue:[NSNumber numberWithDouble:self.userCoordinate.longitude] forKey:@"lon"];
        [toReturn setValue:self.userPlaces forKey:@"userPlaces"];
    
        return [NSDictionary dictionaryWithDictionary:toReturn];
    }
    

    All the key are now present inside the output dictionary!!!

    This problem drove me crazy to understand but my question is ... There is any reason couse the second method works better then the first one??

    I didn't find a reason for it.

  • Admin
    Admin over 12 years
    If that’s the case (and it probably is), the OP would have caught it by using -[NSMutableDictionary setObject:forKey:] instead of -[NSMutableDictionary setValue:forKey:]. The former is the canonical method in NSMutableDictionary to add objects to the dictionary and it raises an exception when trying to add a nil object; the latter is a KVC method that, when sent to an NSMutableDictionary with a nil value, will attempt to remove the corresponding key and won’t throw an exception.
  • Matthias Bauch
    Matthias Bauch over 12 years
    I totally forgot that setValue:forKey: allows nil and setObject:forKey: doesn't.
  • Ans
    Ans over 8 years
    I was looking for something else, but this idea is good. So voting up.