Как определить, является ли NSString нулевым? - PullRequest
53 голосов
/ 16 апреля 2011

У меня есть фрагмент кода, который обнаруживает, если NSString равен NULL, nil и т. Д. Однако, он вылетает.Вот мой код:

NSArray *resultstwo = [database executeQuery:@"SELECT * FROM processes WHERE ready='yes' LIMIT 0,1"];
for (NSDictionary *rowtwo in resultstwo) {

NSString *getCaption = [rowtwo valueForKey:@"caption"];

if (getCaption == NULL) {
theCaption = @"Photo uploaded...";
} else if (getCaption == nil) {
theCaption = @"Photo uploaded...";
} else if ([getCaption isEqualToString:@""]) {
theCaption = @"Photo uploaded...";
} else if ([getCaption isEqualToString:@" "]) {
theCaption = @"Photo uploaded...";
}

}

И вот ошибка:

Завершение работы приложения из-за необработанного исключения 'NSInvalidArgumentException', причина: '-[NSNull isEqualToString:]: нераспознанный селектор отправленк примеру 0x3eba63d4 '

Я что-то не так делаю?Нужно ли делать это по-другому?

Ответы [ 5 ]

168 голосов
/ 16 апреля 2011

Значение NULL для объектов Objective C (тип id) равно nil.

Пока NULL используется для C указателей (тип void *).

(В итоге оба получают одинаковое значение (0x0). Однако они различаются по типу.)

В Объектив-C :

  • nil (все строчные буквы) пусто указатель на объект Objective C .
  • Nil (с большой буквы) - нулевой указатель в Objective-C класс .
  • NULL (все заглавные буквы) - нулевой указатель на что-нибудь еще ( C указатели , то есть) .
  • [NSNull null] - это синглтон для ситуаций, когда использование ноля невозможно (добавление / получение ноля к / от NSArray с, например)

In Objective-C ++ :

  • Все вышеперечисленное , плюс:
  • null (строчные буквы) или nullptr ( C ++ 11 или более поздние) - нулевой указатель на C ++ объектов .

Поэтому для проверки по nil следует либо сравнить с nil (или NULL соответственно) явно :

if (getCaption == nil) ...

или пусть ObjC / C сделать это неявно для вас:

if (!getCaption) ...

Это работает, поскольку каждое выражение в C (и с Objective-C , являющимся его надмножеством) имеет неявное логическое значение:

expression != 0x0 => true
expression == 0x0 => false

Теперь при проверке NSNull это, очевидно, не сработает, поскольку [NSNull null] возвращает указатель на единичный экземпляр NSNull, а не nil, и, следовательно, он не равен 0x0.

Таким образом, для сравнения с NSNull можно использовать:

if ((NSNull *)getCaption == [NSNull null]) ...

или (предпочтительно, см. Комментарии):

if ([getCaption isKindOfClass:[NSNull class]]) ...

Имейте в виду, что последний (с использованием вызова сообщения) вернет false, если getCaption окажется nil, что, хотя формально правильно, может не соответствовать ожидаемому / желаемому.

Следовательно, если одному (по какой-либо причине) необходимо проверить по обоим nil / NULL и NSNull, нужно будет объединить эти две проверки:

if (!getCaption || [getCaption isKindOfClass:[NSNull class]]) ...

Для получения справки о формировании эквивалентных положительных проверок см. Законы Де Моргана и логическое отрицание .

Редактировать: NSHipster.com только что опубликовал отличную статью о тонких различиях между нулями, нулями и т. Д.

24 голосов
/ 16 апреля 2011

Вы должны использовать

if ([myNSString isEqual:[NSNull null]])

Это проверит, равен ли объект myNSString объекту NSNull.

6 голосов
/ 24 ноября 2014

Предпочтительным способом проверки для NSNULL является

if(!getCaption || [getCaption isKindOfClass:[NSNull class]])   
2 голосов
/ 23 февраля 2016

Просто проверьте с этим кодом:

NSString *object;

if(object == nil)

Это должно работать.

2 голосов
/ 29 февраля 2012
if([getCaption class] == [NSNull class])
    ...

Вы также можете сделать

if([getCaption isKindOfClass:[NSNull class]])
    ...

, если хотите быть в будущем против новых подклассов NSNull.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...