【问题标题】:About -(NSDictionary)dictionaryWithObjectsAndKeys: and关于 -(NSDictionary)dictionaryWithObjectsAndKeys: 和
【发布时间】:2011-11-22 20:50:29
【问题描述】:

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

在我的一个类中,我声明了一个非常简单的实例方法 -(NSDictionary)dictionary; 就是这样实现的:

- (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];
    }

声明此方法后,我的返回字典中没有 @"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];
}

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

这个问题让我发疯了,但我的问题是...... 有什么理由让第二种方法比第一种更好用吗??

我没有找到原因。

【问题讨论】:

  • 请注意,将对象添加到字典的规范方法是-setObject:forKey:。您正在使用-setValue:forKey:,这是一种 KVC 方法,并且在我对 fluchtpunkt 的回答的评论中描述了一种特殊的行为。

标签: iphone nsdictionary foundation


【解决方案1】:

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

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

【讨论】:

  • 如果是这种情况(很可能是这样),那么 OP 会使用 -[NSMutableDictionary setObject:forKey:] 而不是 -[NSMutableDictionary setValue:forKey:] 来捕获它。前者是NSMutableDictionary 中向字典添加对象的规范方法,尝试添加nil 对象时会引发异常;后者是一个 KVC 方法,当发送到具有 nil 值的 NSMutableDictionary 时,将尝试删除相应的键并且不会抛出异常。
  • 我完全忘记了setValue:forKey: 允许 nil 而setObject:forKey: 不允许。
【解决方案2】:

类似于下面的代码解决了我的问题,但同样的异常:

(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];
}

【讨论】:

  • 我在寻找别的东西,但这个想法很好。所以投票吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
相关资源
最近更新 更多