关于 - (NSDictionary)dictionaryWithObjectsAndKeys:和

Gab*_*ele 21 iphone nsdictionary foundation

我有一个非常有趣的问题.

在我的一个类中,我声明了一个非常简单的实例方法 - (NSDictionary)字典; 这是以这种方式实现的:

- (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];
    }
Run Code Online (Sandbox Code Playgroud)

声明了这个方法,我的返回字典中没有@"userPlaces"键(self.userPlace显然是有价值的并且充满了对象).

所以我改变了一下这样的方法:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

现在所有的键都存在于输出字典中!

这个问题让我疯狂地理解,但我的问题是......有任何理由第二种方法比第一种方法更好吗?

我找不到理由.

Mat*_*uch 38

[NSDictionary dictionaryWithObjectsAndKeys:停止在找到nil值时添加对象.

因此,您尝试在第一个代码中添加的对象之一很可能是nil.

  • 如果是这种情况(并且它可能是),那么OP将通过使用` - [NSMutableDictionary setObject:forKey:]`而不是` - [NSMutableDictionary setValue:forKey:]`来捕获它.前者是`NSMutableDictionary`中的规范方法,用于向字典添加对象,并在尝试添加`nil`对象时引发异常; 后者是一个KVC方法,当发送到带有`nil`值的`NSMutableDictionary`时,它将尝试删除相应的键,不会抛出异常. (7认同)

use*_*957 7

类似于下面的代码的东西解决了我的问题相同的例外:

(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];
}
Run Code Online (Sandbox Code Playgroud)