Как правильно проверить наличие нулевой строки в Objective-C? - PullRequest
177 голосов
/ 09 июня 2009

Я использовал это в своем приложении для iPhone

if (title == nil) {
    // do something
}

но выдает какое-то исключение, и консоль показывает, что заголовок "(null)".

Итак, я использую это сейчас:

if (title == nil || [title isKindOfClass:[NSNull class]]) {
    //do something
}

В чем разница и как определить, является ли строка нулевой?

Ответы [ 18 ]

386 голосов
/ 10 июня 2009

Как уже отмечали другие, в Какао / Objective C. есть много видов "нулей". Но еще одна вещь, на которую стоит обратить внимание, это то, что [title isKindOfClass: [NSNull class]] бессмысленно сложен, поскольку [NSNull null] задокументирован быть одиноким, так что вы можете просто проверить равенство указателей. См. Темы для какао: использование Null .

Итак, хороший тест может быть:

if (title == (id)[NSNull null] || title.length == 0 ) title = @"Something";

Обратите внимание, как вы можете использовать тот факт, что даже если title равно nil, title.length вернет 0 / nil / false, т. Е. 0 в этом случае, так что вам не нужно это делать в особых случаях. Это то, к чему люди, плохо знакомые с Objective C, испытывают трудности с привыканием, особенно из других языков, где сообщения / методы обращаются к nil crash.

24 голосов
/ 09 июня 2009

это так же просто, как

if([object length] >0)
{
  // do something
}

помните, что в цели C, если объект равен нулю, в качестве значения возвращается 0

Это даст вам как нулевую строку, так и строку длиной 0.

6 голосов
/ 09 июня 2009

См. Следующие статьи на этом сайте:

Я думаю, что ваша ошибка связана с чем-то другим, так как вам не нужно выполнять дополнительную проверку.

Также см. Этот связанный вопрос: Правильная проверка текстового столбца nil sqlite

5 голосов
/ 07 мая 2012

Что со всеми этими "работает на меня ответы"? Мы все пишем на одном языке, а правила

  1. Убедитесь, что ссылка не ноль
  2. Проверьте и убедитесь, что длина строки не равна 0

Это то, что будет работать для всех. Если данное решение только «работает для вас», это только потому, что поток приложения не допускает сценарий, в котором ссылка может быть нулевой или длина строки равна 0. Правильный способ сделать это - метод, который будет обрабатывать что вы хотите во всех случаях.

5 голосов
/ 17 сентября 2013

Я обнаружил, что для того, чтобы действительно сделать это правильно, вам нужно будет сделать что-то похожее на

if ( ( ![myString isEqual:[NSNull null]] ) && ( [myString length] != 0 ) ) {
}

В противном случае вы получите странные ситуации, когда контроль все равно будет обходить ваш чек. Я не сталкивался с тем, который проходит через isEqual и проверки длины.

4 голосов
/ 09 июня 2009

Если вы хотите проверить все ноль / пустые объекты (например, пустые строки или пустые массивы / наборы), вы можете использовать следующее:

static inline BOOL IsEmpty(id object) {
    return object == nil
        || ([object respondsToSelector:@selector(length)]
        && [(NSData *) object length] == 0)
        || ([object respondsToSelector:@selector(count)]
        && [(NSArray *) object count] == 0);
}
3 голосов
/ 02 января 2014

Есть две ситуации:

Возможно, что объект [NSNull null], или это невозможно.
Ваше приложение обычно не должно использовать [NSNull null];, вы используете его, только если вы хотите поместить объект " null " в массив или использовать его в качестве значения словаря. И тогда вы должны знать, какие массивы или словари могут содержать нулевые значения, а какие нет.
Если вы считаете, что массив никогда не содержит [NSNull null] значений, не проверяйте его. Если есть [NSNull null], вы можете получить исключение, но это нормально: исключения Objective-C указывают на ошибки программирования. И у вас есть программная ошибка, которую нужно исправить, изменив некоторый код.

Если объект может быть [NSNull null], то вы можете проверить это довольно просто, протестировав
(object == [NSNull null]). Вызов isEqual или проверка класса объекта - нонсенс. Существует только один [NSNull null] объект, и простой старый оператор C проверяет его в порядке, самым простым и эффективным способом.

Если вы проверяете NSString объект, который не может быть [NSNull null] (потому что вы знаете, что он не может быть [NSNull null] или потому что вы только что проверили, что он отличается от [NSNull null], тогда вам нужно спросить себя, как вы хотите обрабатывать пустую строку, которая имеет длину 0. Если вы обрабатываете это null строка как nil, тогда test (object.length == 0). object.length вернет 0, если object == nil, поэтому этот тест охватывает ноль объекты и строки длиной 0. Если вы обрабатываете строку длиной 0, отличную от нулевой строки, просто проверьте, если object == nil.

Наконец, если вы хотите добавить строку в массив или словарь, и строка может иметь значение nil, у вас есть возможность не добавлять ее, заменить ее на @"" или заменить ее [NSNull null]. Замена на @"" означает, что вы теряете возможность различать «без строки» и «строка длины 0». Замена на [NSNull null] означает, что вы должны писать код при доступе к массиву или словарю, который проверяет объекты [NSNull null].

2 голосов
/ 25 мая 2018

Вот макрос, который я использую для безопасной строки вместо получения строки «(null)» в UILabel, например:

#define SafeString(STRING) ([STRING length] == 0 ? @"" : STRING)

допустим, у вас есть свойство класса и имени члена, а имя равно nil:

NSLog(@"%@", member.name); // prints (null) on UILabel

с макросом:

NSLog(@"%@", SafeString(member.name)); // prints empty string on UILabel

красиво и чисто.

2 голосов
/ 13 декабря 2014

Вы просто проверяете на ноль

if(data[@"Bonds"]==nil){
  NSLog(@"it is nil");
}

или

if ([data[@"Bonds"] isKindOfClass:[NSNull class]]) {
    NSLog(@"it is null");
}
1 голос
/ 07 марта 2015
@interface NSString (StringFunctions)
- (BOOL) hasCharacters;
@end

@implementation NSString (StringFunctions)
- (BOOL) hasCharacters {
    if(self == (id)[NSNull null]) {
        return NO;
    }else {
        if([self length] == 0) {
            return NO;
        }
    }
    return YES;
}
@end

NSString *strOne = nil;
if([strOne hasCharacters]) {
    NSLog(@"%@",strOne);
}else {
    NSLog(@"String is Empty");
}

Это будет работать в следующих случаях: NSString *strOne = @"" ИЛИ NSString *strOne = @"StackOverflow" ИЛИ NSString *strOne = [NSNull null] ИЛИ NSString *strOne.

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