NSDictionary 为不同的键返回相同的值
NSDictionary returning same value for different keys
我有一些 Obj-C 代码使用 NSNumber
s 作为字典中的键。我发现了一个错误,我追踪到一些非常奇怪的行为,如果使用 NSDecimalNumber
(NSNumber
的子类)访问字典,它总是 return 相同的元素。这是一个展示行为的小程序,NSLogs 输出问题:
#define LONGNUMBER1 5846235266280328403
#define LONGNUMBER2 5846235266280328404
- (void) wtfD00d {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSNumber *key1 = [NSNumber numberWithLongLong:LONGNUMBER1];
NSNumber *key2 = [NSNumber numberWithLongLong:LONGNUMBER2];
dict[key1] = @"ONE";
dict[key2] = @"TWO";
NSNumber *decimalKey1 = [NSDecimalNumber numberWithLongLong:LONGNUMBER1];
NSNumber *decimalKey2 = [NSDecimalNumber numberWithLongLong:LONGNUMBER2];
NSString *value1 = dict[decimalKey1];
NSString *value2 = dict[decimalKey2];
NSLog(@"Number of entries in dictionary = %lu", (unsigned long)dict.count); // 2
NSLog(@"%@", dict); // 5846235266280328403 = ONE
// 5846235266280328404 = TWO
NSLog(@"Value1 = %@, Value 2 = %@", value1, value2); // Value1 = ONE, Value 2 = ONE
NSLog(@"key2 = decimalKey2: %@", [key2 isEqual:decimalKey2] ? @"True" : @"False"); // key2 isEqual decimalKey2: True
NSLog(@"decimalKey1 = decimalKey2: %@", [decimalKey1 isEqual:decimalKey2] ? @"True" : @"False"); // decimalKey1 isEqual decimalKey2: False
}
请注意,第 3 行日志显示 value1 和 value2 相同。为什么会发生这种情况?
这是因为我们在 CoreData 中有几个类型为 Decimal 的字段,它们作为 NSNumber 从 CoreData 中出来。我们发现我们必须玩游戏才能避免这种奇怪的行为,但我不明白为什么它首先会发生。我希望任何人都能提供有关查找失败原因的任何见解。
我觉得NSNumber
和NSDecimalNumber
比较的时候是用doubleValue
来比较的
您可以在 apple 中为此报告错误
我只能建议避免NSNumber<->NSDecimalNumber
比较并在此处使用:
NSString *value1 = dict[@(decimalKey1.longLongValue)];
NSString *value2 = dict[@(decimalKey2.longLongValue)];
我有一些 Obj-C 代码使用 NSNumber
s 作为字典中的键。我发现了一个错误,我追踪到一些非常奇怪的行为,如果使用 NSDecimalNumber
(NSNumber
的子类)访问字典,它总是 return 相同的元素。这是一个展示行为的小程序,NSLogs 输出问题:
#define LONGNUMBER1 5846235266280328403
#define LONGNUMBER2 5846235266280328404
- (void) wtfD00d {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSNumber *key1 = [NSNumber numberWithLongLong:LONGNUMBER1];
NSNumber *key2 = [NSNumber numberWithLongLong:LONGNUMBER2];
dict[key1] = @"ONE";
dict[key2] = @"TWO";
NSNumber *decimalKey1 = [NSDecimalNumber numberWithLongLong:LONGNUMBER1];
NSNumber *decimalKey2 = [NSDecimalNumber numberWithLongLong:LONGNUMBER2];
NSString *value1 = dict[decimalKey1];
NSString *value2 = dict[decimalKey2];
NSLog(@"Number of entries in dictionary = %lu", (unsigned long)dict.count); // 2
NSLog(@"%@", dict); // 5846235266280328403 = ONE
// 5846235266280328404 = TWO
NSLog(@"Value1 = %@, Value 2 = %@", value1, value2); // Value1 = ONE, Value 2 = ONE
NSLog(@"key2 = decimalKey2: %@", [key2 isEqual:decimalKey2] ? @"True" : @"False"); // key2 isEqual decimalKey2: True
NSLog(@"decimalKey1 = decimalKey2: %@", [decimalKey1 isEqual:decimalKey2] ? @"True" : @"False"); // decimalKey1 isEqual decimalKey2: False
}
请注意,第 3 行日志显示 value1 和 value2 相同。为什么会发生这种情况?
这是因为我们在 CoreData 中有几个类型为 Decimal 的字段,它们作为 NSNumber 从 CoreData 中出来。我们发现我们必须玩游戏才能避免这种奇怪的行为,但我不明白为什么它首先会发生。我希望任何人都能提供有关查找失败原因的任何见解。
我觉得NSNumber
和NSDecimalNumber
比较的时候是用doubleValue
来比较的
您可以在 apple 中为此报告错误
我只能建议避免NSNumber<->NSDecimalNumber
比较并在此处使用:
NSString *value1 = dict[@(decimalKey1.longLongValue)];
NSString *value2 = dict[@(decimalKey2.longLongValue)];