NSValue
, NSNumber
, ... должны создаваться из значения и всегда содержать его. Тестирование на конкретное значение, такое как 0
, работает только в том случае, если оно не находится в диапазоне допустимых значений, с которыми вы работаете.
В редком случае, когда код более прост для работы, если у вас есть значение, которое представляет «неверно» или «не установлено» и вы не можете использовать nil
(например, со стандартными контейнерами) вместо него можно использовать NSNull
.
В вашем первом примере это может быть:
[dict setValue:[NSNull null] forKey:@"emptyValue"];
if ([dict objectForKey:@"emptyValue"] == [NSNull null]) {
// ...
}
Но учтите, что вы можете просто не вставлять (или удалять) это значение, если вам не нужно различать nil
(то есть не в контейнере) и, скажем, "неверно" :
if ([dict objectForKey:@"nonExistent"] == nil) {
// ...
}
Что касается второго примера , -intValue
дает вам 0
- но просто потому, что отправка сообщений на nil
возвращает 0
. Вы также можете получить 0
например для NSNumber
, для которого intValue
ранее было установлено 0
, что может быть допустимым значением.
Как я уже писал выше, вы можете сделать что-то подобное, только если 0
не является допустимым значением для вас . Обратите внимание на для вас , то, что работает лучше всего, полностью зависит от ваших требований.
Позвольте мне попытаться обобщить :
Вариант № 1:
Если вам не нужны все значения из диапазона чисел, вы можете использовать одно (0
или -1
или ...) и -intValue
/ ..., чтобы специально представлять «пусто» . Это, очевидно, не так для вас.
Вариант № 2:
Вы просто не сохраняете и не удаляете значения из контейнера, если они "пустые" :
// add if not empty:
[dict setObject:someNumber forKey:someKey];
// remove if empty:
[dict removeObjectForKey:someKey];
// retrieve number:
NSNumber *num = [dict objectForKey:someKey];
if (num == nil) {
// ... wasn't in dictionary, which represents empty
} else {
// ... not empty
}
Однако это означает, что нет никакой разницы между пустыми ключами и ключами, которые никогда не существуют или являются незаконными.
Вариант № 3:
В некоторых редких случаях удобнее хранить все ключи в словаре и представлять «пусто» с другим значением. Если вы не можете использовать один из диапазона номеров, мы должны ввести что-то по-другому, так как NSNumber
не имеет понятия «пусто» . Какао уже имеет NSNull
для таких случаев:
// set to number if not empty:
[dict setObject:someNumber forKey:someKey];
// set to NSNull if empty:
[dict setObject:[NSNull null] forKey:someKey];
// retrieve number:
id obj = [dict objectForKey:someKey];
if (obj == [NSNumber null]) {
// ... empty
} else {
// ... not empty
NSNumber *num = obj;
// ...
}
Этот параметр теперь позволяет различать «пусто» , «не пусто» и «не в контейнере» (например, недопустимый ключ).