Сравните NSNumber с int

У меня простой вопрос (я думаю): Я пытаюсь сравнить NSNumber с int, чтобы увидеть, если он равен 0 или 1. Вот код:

id i = [dictionary objectForKey:@"error"]; //class = NSCFNumber

NSLog(@"%@ == 0 -> %@", i, i == 0);
NSLog(@"%@ == 0 -> %@", i, [i compare:[NSNumber numberWithBool:NO]]);

Я пробовал это для методов, но получаю null как результат:

2010-10-17 21:57:49.065 Api[15152:a0f] 0 == 0 -> (null)
2010-10-17 21:57:49.065 Api[15152:a0f] 0 == 0 -> (null)

Можете ли вы мне помочь?

Ответы

Ответ 1

  • Результатом сравнения является BOOL, который не является объектом Objective-C. Поэтому вы должны не печатать его с помощью %@. Попробуйте %d вместо (показывает 0 или 1).

  • [a compare:b] возвращает -1, если a < b, 0, если a == b и 1, если a > b. Таким образом, ожидается ваш второй результат.

  • Вы не можете напрямую сравнивать NSNumber с целым числом. Это i == 0 на самом деле сравнение указателей, которое проверяет, является ли i NULL (0), что, конечно, FALSE, если это число существует. Таким образом, ожидается и 1-й результат.

  • Если вы хотите проверить равенство, используйте [a isEqualToNumber:b]. Кроме того, вы можете извлечь целое число с помощью [a intValue] и сравнить с другим целым числом напрямую.

Итак, следующие действия должны работать:

NSLog(@"%@ == 0 -> %d", i, [i isEqualToNumber:[NSNumber numberWithInt:0]]);
NSLog(@"%@ == 0 -> %d", i, [i intValue] == 0);

Если "число" на самом деле является логическим, лучше взять -boolValue.

NSLog(@"%@ == 0 -> %d", i, ! [i boolValue]);

Ответ 2

Здесь вы сравниваете указатель объекта я с 0, который, я боюсь, не то, что вы хотите.

Скорее всего, вы захотите сравнить значение i:

if ([i intValue]==0) {
  ...
}

Ответ 3

Вы можете легко написать:

NSNumber *number = [NSNumber numberWithInt:123];
int integer = 1234;

NSLog(@"%@ == %i : %i", number, integer, [number intValue] == integer);

Выход должен быть

123 == 1234 : 0


Надеюсь, я смогу вам помочь!

Ответ 4

У вас есть две проблемы:

  • Вы запутываете объект NSNumber со значением, которое оно представляет.
  • Строка формата NSLog не соответствует типам аргументов, которые вы предоставляете.

Относительно первой проблемы: i - это адрес, возможно, что-то вроде 0x1f84b. Когда вы проверяете, i == 0, вы проверяете, есть ли i == NULL. В этом случае это означает, что вы проверяете, присутствовала ли ключевая "ошибка" в словаре или нет, поскольку поиск несуществующих ключей завершает a NULL.

[i intValue], с другой стороны, является целым числом. Если NSNumber содержит значение, представляемое как целое число, это будет значение NSNumber. Это то, что вы видите при печати описания NSNumber с помощью спецификатора формата %@.

В отношении второй проблемы: сравнения в C и Objective-C возвращают целое число, либо 0 (что означает false), либо 1 (что означает true). Чтобы напрямую распечатать результат сравнения, вам необходимо использовать спецификатор целочисленного формата. На самом деле существует два таких спецификатора: %i и %d. Вы можете обернуть результат сравнения в NSNumber и использовать %@ для печати, но это больше, чем нужно.

Итак, вот что вы должны делать:

NSNumber *i = [dictionary objectForKey:@"error"];
BOOL haveValue = (i != NULL);
if (haveValue) {
    int iValue = [i intValue];
    NSLog(@"%d == 0 -> %d", iValue, iValue == 0);
    NSLog(@"%@ compared to 0 -> %d", i, [i compare:[NSNumber numberWithInt:0]]);
} else {
    NSLog(@"*** Dictionary has no value for key \"error\"!");
}

Ответ 5

Это сработало

if (thevariable.intValue==0) {
  ...
}