Как определить, является ли NSString null?


у меня есть кусок кода, который обнаруживает, если 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 53

5 ответов:

The NULL значение Objective-C objects (типа id) составляет nil.

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

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

на С:

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

In Objective-C++:

  • все выше плюс:
  • null(нижний регистр) или nullptr (C++11 или более поздней версии) является нулевым указателем на объекты C++.

чтобы проверить против nil вы должны либо сравнить с nil (или NULL соответственно) явно:

if (getCaption == nil) ...

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

if (!getCaption) ...

это работает, как каждое выражение в C (и с С будучи его надмножеством) имеет неявное логическое значение:

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

теперь при проверке NSNull это, очевидно, не будет работать как [NSNull null] возвращает указатель на экземпляр Singleton 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]]) ...

за помощью по формированию эквивалентна положительной проверки посмотреть законы де Моргана и логическое отрицание.

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

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

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

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

предпочтительный способ проверить NSNULL и

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

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

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

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

просто проверьте с помощью этого кода:

NSString *object;

if(object == nil)

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