NSDictionary, возвращающий одно и то же значение для разных ключей - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть некоторый код Obj-C, который использует NSNumber s в качестве ключей в словаре. Я обнаружил ошибку, которую я отследил до очень странного поведения, когда при доступе к словарю с использованием NSDecimalNumber (подкласс NSNumber) он всегда возвращал один и тот же элемент. Вот небольшая программа, которая демонстрирует поведение и 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-я строка журнала показывает, что значения1 и значение2 совпадают. ПОЧЕМУ это происходит?

Это произошло потому, что у нас есть несколько полей в CoreData с типом Decimal, и они выходят из CoreData как NSNumber. Мы обнаружили, что нам пришлось играть в игры, чтобы обойти это странное поведение, и я не понимаю, почему это происходит в первую очередь. Мне бы очень хотелось, чтобы кто-нибудь мог понять, почему неудачные поиски.

1 Ответ

0 голосов
/ 05 сентября 2018

Я думаю, что когда NSNumber и NSDecimalNumber сравниваются друг с другом, они используют doubleValue для сравнения.

Вы можете сообщить об ошибке в Apple для этого

Могу предложить только избежать NSNumber<->NSDecimalNumber сравнения и использовать здесь:

NSString *value1 = dict[@(decimalKey1.longLongValue)];
NSString *value2 = dict[@(decimalKey2.longLongValue)];
...