Як перевірити, чи рядок порожній у Objective-C?


Відповіді:


1156

Ви можете перевірити, чи є [string length] == 0. Це дозволить перевірити, чи це дійсна, але порожня рядок (@ ""), а також чи нуль, оскільки виклик lengthна nil також поверне 0.


12
Є кілька дуже рідкісних NSStrings, де це призведе до помилкового негативу (мовляв, рядок не порожній, коли в практичних цілях це є). Розглянемо @"\u200B"(що складаються тільки з символів Unicode ZERO WIDTH ПРОСТІР . Друкуючи його з надрукує 0 символів (перевірити , використовуючи моно шрифт), але String.length дасть 1. Є інші символи Unicode (наприклад , ОБ'ЄКТ ЗАМІНИ ХАРАКТЕРУ ) , які ведуть себе таким же чином. Ви можете отримати останнє під час розбору тексту PDF.
fzwo

43
@fzwo не бути дупою, але теоретично це не дає помилкового негативу. Він поводиться точно так, як ви очікували. Ваша інтерпретація того, що ZERO WIDTH SPACEнасправді насправді не має значення, оскільки @"\u200B" все-таки є символом, тому якщо ви перевірите, чи є рядок порожнім, він скаже, що це не тому, що в ньому є символ. Це просто не для друку, що відповідає стандарту Unicode.
bmeulmeester

2
Звичайно, це технічно правильно, я не обговорюю це. Я просто хочу застерегти, що це може не виявляти наміченої або очікуваної поведінки, саме тому я написав "для практичних цілей". Це залежить від передбачуваного значення "порожній".
fzwo

4
Це не хибний негатив. "Простір з нульовою вартістю" - це символ унікоду, як і будь-який інший. Це просто "варто запам'ятати", якщо це стосується вашої програми. (Чудово задумавшись, fzwo!)
Fattie

2
Дай мені знати , якщо я помиляюся, але я думаю , що ви могли б опустити == 0 частини і додати заперечення перед: ![string length]. Здається, більш чисто.
damirstuhec

126

Відповідь Марка правильна. Але я скористаюся цією можливістю, щоб включити вказівник на узагальнений Віл Шиплі isEmpty, яким він поділився у своєму блозі :

static inline BOOL IsEmpty(id thing) {
return thing == nil
|| ([thing respondsToSelector:@selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:@selector(count)]
&& [(NSArray *)thing count] == 0);
}

26
Якщо ви хочете, щоб це було дуже узагальнено, можна застосувати цю логіку як категорію на NSObject, а не використовувати статичний метод, як показано тут.
Brad The App Guy

16
Як не дивно, це насправді не перевіряє наявність [NSNull null].
Пітер Н Льюїс

14
Якщо ви опинилися в ситуації, коли ви не знаєте, який тип об'єкта ви перевіряєте, я думаю, це працює. Однак я пропоную, що якщо ви не знаєте, чи є об’єктом NSData або NSArray, у вас виникнуть більші проблеми. Який ваш наступний макрос буде після цього дзвінка, condensToSingleNSData (id id)? expandToNSArray (річ з id)? Рано чи пізно ви запитаєте, з яким класом ви маєте справу, краще це зробити за першою довідкою.
Бран

1
@BradSmith, можна створити для нього категорію, але нульові значення не будуть зараховані, оскільки метод не буде викликаний. Наприклад, якщо thing = nil, [thing IsEmpty] не буде викликано і завжди повертає false / NO. Щоб перевірити наявність нуля, повинен бути параметр. Об'єкти Nil не можуть порівнювати себе як нулі через категорію.
Кріс

3
@chris, тоді ви можете змінити метод категорії на -isNotEmpty:)
nielsbot

93

Перший підхід дійсний, але не працює, якщо у вашій рядку є порожні пробіли ( @" "). Тому ви повинні очистити ці білі проміжки перед тестуванням.

Цей код очищає всі порожні пробіли з обох сторін рядка:

[stringObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];

Хороша ідея - створити один макрос, тому вам не доведеться вводити цю лінію монстра:

#define allTrim( object ) [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ]

Тепер ви можете використовувати:

NSString *emptyString = @"   ";

if ( [allTrim( emptyString ) length] == 0 ) NSLog(@"Is empty!");

3
Навіщо використовувати макроси, коли вони не потрібні? У цьому випадку безпека будь-якого типу жертвується без жодної реальної вигоди.
EM

Це просто для зручності, якщо ви хочете написати "[object stringObject stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]" кожного разу, коли ви хочете перевірити, чи один рядок порожній, залежить від вас.
Команда розвитку SEQOY

18
що краще обслуговувати NSStringкатегорію, яка додає метод під назвою, trimmedStringякий робить саме те, що ви написали.
Дейв ДеЛонг

2
Зауважте, що Apple whitespaceCharacterSetне включає нові рядки! Ось категорія, про яку я писав, включаючи trimдеякі інші корисні методи: github.com/alexch/unsuck/blob/master/unsuck/NSString%2BUnsuck.m github.com/alexch/unsuck/blob/master/unsuckTests/…
AlexChaffee

@EM Я не прихильник макросів, але я не розумію, що стосується безпеки вашого типу. Під час компіляції макрос замінюється його вмістом, тому якщо ви викликаєте макрос чимось відмінним від NSString, ви все одно отримаєте повідомлення від компілятора. Категорії були б набагато кращими.
Zmaster

32

Одне з найкращих рішень, які я коли-небудь бачив (краще, ніж у Метта Г) - це вдосконалена вбудована функція, яку я взяв на деякий репо-рейтинг Git Hub (той, що знаходиться у Віла Шиплі, але я не можу знайти посилання):

// Check if the "thing" passed is empty
static inline BOOL isEmpty(id thing) {
    return thing == nil
    || [thing isKindOfClass:[NSNull class]]
    || ([thing respondsToSelector:@selector(length)]
        && [(NSData *)thing length] == 0)
    || ([thing respondsToSelector:@selector(count)]
        && [(NSArray *)thing count] == 0);
}

2
Це робота Віла Шиплі. FYI, ти можеш змінити [thing isKindOfClass: [NSNull class]] на just (thing == [NSNull null])
Steve N

Ф'ю .... саме те, що я шукав. Я зійшов з розуму, намагаючись з'ясувати, чому моя функція "cellForRowAtIndexPath" вийшла з ладу через нульові рядки (і я не міг наздогнати проблему). Ця функція прекрасно вирішила її.
Майк Гледхілл

Копія коментаря @Brane: Якщо ви знаходитесь у ситуації, коли ви не знаєте, який тип об’єкта ви перевіряєте, я думаю, це працює. Однак я пропоную, що якщо ви не знаєте, чи є об’єктом NSData або NSArray, у вас виникнуть більші проблеми. Який наступний макрос буде після цього дзвінка condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Рано чи пізно ви запитаєте, з яким класом ви маєте справу, краще це зробити за першою довідкою.
Cœur

16

Вам слід краще використовувати цю категорію:

@implementation NSString (Empty)

    - (BOOL) isWhitespace{
        return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]length] == 0);
    }

@end

6
Це визначення повинно зробити висновок про те, що рядок "/ r / n / r / n" порожній, коли його явно немає - він містить пробіл. Ваша функція справді: - (BOOL) isWhitespace (NSString *);
JBRWilkinson

6
Наслідок цього. Я реалізував цю категорію, і є поворот. Якщо ви називаєте це на рядку нуля, ця функція ніколи не викликається, і ви отримуєте назад NO (або те, що оцінюється як NO) як повернене значення. Тоді ви думаєте, що це не порожньо ... Це може спрацювати, якщо ім’я було заповнене чи щось подібне.
Ян

Я здогадуюсь, правильною категорією було б: @implementation NSString (Empty) - (BOOL) empty{ return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]length] == 0); } @end Як поєднання відповіді Марка та Кайла.
пальма

12

Я ставлю це:

@implementation NSObject (AdditionalMethod)
-(BOOL) isNotEmpty
{
    return !(self == nil
    || [self isKindOfClass:[NSNull class]]
    || ([self respondsToSelector:@selector(length)]
        && [(NSData *)self length] == 0)
    || ([self respondsToSelector:@selector(count)]
        && [(NSArray *)self count] == 0));

};
@end

Проблема полягає в тому, що якщо "self" є нульовою, ця функція ніколи не викликається. Він поверне помилкове, що бажано.


Найкраще рішення з а) - це метод екземпляра і b) категорія c) нульовий випадок на собі - це обробка "isNotEmpty" Thx!
Денис

Чудова ідея, надто погано -(BOOL)isEmpty{ return ![self isNotEmpty]}не буде працювати на категорії.
Альстон

Копія коментаря @Brane: Якщо ви знаходитесь у ситуації, коли ви не знаєте, який тип об’єкта ви перевіряєте, я думаю, це працює. Однак я пропоную, що якщо ви не знаєте, чи є об’єктом NSData або NSArray, у вас виникнуть більші проблеми. Який наступний макрос буде після цього дзвінка condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Рано чи пізно ви запитаєте, з яким класом ви маєте справу, краще це зробити за першою довідкою.
Cœur

11

Інший варіант полягає в перевірці , якщо вона дорівнює @""з isEqualToString:приблизно так:

if ([myString isEqualToString:@""]) {
    NSLog(@"myString IS empty!");
} else {
    NSLog(@"myString IS NOT empty, it is: %@", myString);
}

11

Просто передайте рядок наступному методу:

+(BOOL)isEmpty:(NSString *)str
{
    if(str.length==0 || [str isKindOfClass:[NSNull class]] || [str isEqualToString:@""]||[str  isEqualToString:NULL]||[str isEqualToString:@"(null)"]||str==nil || [str isEqualToString:@"<null>"]){
        return YES;
    }
    return NO;
}

Перегляньте коментарі на stackoverflow.com/questions/21605075/…, чому це неправильно. Також як це краще, ніж інші відповіді тут.
Popeye

6

Просто використовуйте один із if else умов, як показано нижче:

Спосіб 1:

if ([yourString isEqualToString:@""]) {
        // yourString is empty.
    } else {
        // yourString has some text on it.
    }

Спосіб 2:

if ([yourString length] == 0) {
    // Empty yourString
} else {
    // yourString is not empty
}

6

Швидка версія

Незважаючи на те, що це питання об'єктивного С, мені потрібно було скористатися NSStringв Swift, тому я також включу тут відповідь.

let myNSString: NSString = ""

if myNSString.length == 0 {
    print("String is empty.")
}

Або якщо NSStringце необов'язково:

var myOptionalNSString: NSString? = nil

if myOptionalNSString == nil || myOptionalNSString!.length == 0 {
    print("String is empty.")
}

// or alternatively...
if let myString = myOptionalNSString {
    if myString.length != 0 {
        print("String is not empty.")
    }
}

Нормальна Stringверсія Swift є

let myString: String = ""

if myString.isEmpty {
    print("String is empty.")
}

Дивіться також: Перевірити порожній рядок у Swift?


5

Можливо, ця відповідь є дублікатом вже наданих відповідей, але я змінив і змінив в порядку перевірки умов. Будь ласка, зверніться до наведеного нижче коду:

+(BOOL)isStringEmpty:(NSString *)str
    {
        if(str == nil || [str isKindOfClass:[NSNull class]] || str.length==0) {
            return YES;
       }
        return NO;
    }

Це категорія, ви можете побачити, як її створити тут: goo.gl/bRcfn7 . Мені подобається ідея категорії для цього
Даніель Гомес Ріко

Ні, не можна сказати, що це категорія. Якщо ця функція реалізована під категорією класу NSString, то це категорія. Інакше ми можемо назвати цей метод іменем класу, де б ми його не реалізували. Як і Bool isEmptyStr = [MyClassName isStringEmpty: str] Але все ж, буде краще, якщо ми оголосимо його під категорією. Тому що якось нам потрібно також скористатися категоріями.
iDevAmit

4

Ви можете перевірити, чи ваша рядок порожній, чи не мій, використовуючи цей метод:

+(BOOL) isEmptyString : (NSString *)string
{
    if([string length] == 0 || [string isKindOfClass:[NSNull class]] || 
       [string isEqualToString:@""]||[string  isEqualToString:NULL]  ||
       string == nil)
     {
        return YES;         //IF String Is An Empty String
     }
    return NO;
}

Найкраща практика полягає в тому, щоб зробити спільний клас, який скаже UtilityClass, і оголосити цей метод, щоб ви могли використовувати цей метод, просто зателефонувавши до нього через свою програму.


4

У вас є два способи перевірити, чи рядок порожній чи ні:

Припустимо, назва вашого рядка є NSString *strIsEmpty.

Спосіб 1:

if(strIsEmpty.length==0)
{
    //String is empty
}

else
{
    //String is not empty
}

Спосіб 2:

if([strIsEmpty isEqualToString:@""])
{
    //String is empty
}

else
{
    //String is not empty
}

Виберіть будь-який із вищевказаних методів та дізнайтеся, чи рядок порожній чи ні.


3

Просто перевірте довжину рядка

 if (!yourString.length)
 {
   //your code  
 }

повідомлення до NIL поверне нуль або 0, тому не потрібно тестувати на nil :).

Щасливе кодування ...


Я цим користувався стільки разів. Абсолютно не потрібно розширень, категорій і чого ні.
pnizzle

2

Це працює як шарм для мене

Якщо NSStringєs

if ([s isKindOfClass:[NSNull class]] || s == nil || [s isEqualToString:@""]) {

    NSLog(@"s is empty");

} else {

    NSLog(@"s containing %@", s);

}

2

Отже, окрім основної концепції перевірки на наявність довжини рядка менше 1, важливо глибоко розглянути контекст. Мови людини чи комп'ютера або іншим чином можуть мати різні визначення порожніх рядків, і в цих же мовах додатковий контекст може ще більше змінити значення.

Скажімо, порожній рядок означає "рядок, який не містить знаків, значущих у поточному контексті".

Це може означати візуально, оскільки колір і колір тла однакові в атрибутивному рядку. Ефективно порожній.

Це може означати порожні значущі символи. Усі точки або всі тире або всі підкреслення можуть вважатися порожніми. Крім того, порожній із значущих знакових символів може означати рядок, який не має символів, які читач розуміє. Вони можуть бути символами на мові чи символі, визначеними як безглузді для читача. Ми могли б визначити це трохи інакше, щоб сказати, що рядок не містить відомих слів на даній мові.

Можна сказати, що порожнє - це функція відсотка від'ємного простору у наданих гліфах.

Навіть послідовність символів, що не друкуються, без загального візуального зображення, не є справді порожньою. На думку приходять контрольні символи. Особливо низький діапазон ASCII (я здивований, що ніхто не згадував про них, оскільки вони шлангують безліч систем і не є пробілом, оскільки вони зазвичай не мають ні гліфів, ні візуальних показників). І все ж довжина рядка не дорівнює нулю.

Висновок. Довжина одна - це не єдиний показник. Контекстуальне членство в наборі також є досить важливим.

Членство в наборі символів є дуже важливим загальним додатковим заходом. Значущі послідовності також є досить поширеними. (думаю, SETI або криптовалюта або капчу) Також існують додаткові більш абстрактні набори контексту.

Тому добре подумайте, перш ніж вважати, що рядок порожній лише на основі довжини або пробілу.


2

Дуже корисний пост, щоб додати підтримку NSDictionary, а також одну невелику зміну

static inline BOOL isEmpty(id thing) {
    return thing == nil
    || [thing isKindOfClass:[NSNull class]]
    || ([thing respondsToSelector:@selector(length)]
        && ![thing respondsToSelector:@selector(count)]
        && [(NSData *)thing length] == 0)
    || ([thing respondsToSelector:@selector(count)]
        && [thing count] == 0);
}

Копія коментаря @Brane: Якщо ви знаходитесь у ситуації, коли ви не знаєте, який тип об’єкта ви перевіряєте, я думаю, це працює. Однак я припускаю, що якщо ви не знаєте, чи є об’єктом NSData чи NSDictionary, у вас виникнуть більші проблеми. Який наступний макрос буде після цього дзвінка condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Рано чи пізно ви запитаєте, з яким класом ви маєте справу, краще це зробити за першою довідкою.
Cœur

2
- (BOOL)isEmpty:(NSString *)string{
    if ((NSNull *) string == [NSNull null]) {
        return YES;
    }
    if (string == nil) {
        return YES;
    }
    if ([string length] == 0) {
        return YES;
    }
    if ([[string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
        return YES;
    }
    if([[string stringByStrippingWhitespace] isEqualToString:@""]){
        return YES;
    }
    return NO;
}

1
Перші три умови є зайвими, і ви не включили джерело для stringByStrippingWhitespace
маттсвен

2

Найкращий спосіб - використовувати категорію.
Ви можете перевірити наступну функцію. Який має всі умови для перевірки.

-(BOOL)isNullString:(NSString *)aStr{
        if([(NSNull *)aStr isKindOfClass:[NSNull class]]){
            return YES;
        }
        if ((NSNull *)aStr  == [NSNull null]) {
            return YES;
        }
        if ([aStr isKindOfClass:[NSNull class]]){
            return YES;
        }
        if(![[aStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]){
            return YES;
        }
        return NO;
    }

1

Найкращий спосіб у будь-якому випадку - перевірити довжину заданої рядки. Для цього, якщо ваша рядок є myString, код:

    int len = [myString length];
    if(len == 0){
       NSLog(@"String is empty");
    }
    else{
      NSLog(@"String is : %@", myString);
    }


1

Перевір це :

if ([yourString isEqualToString:@""])
{
    NsLog(@"Blank String");
}

Або

if ([yourString length] == 0)
{
    NsLog(@"Blank String");
}

Сподіваюсь, це допоможе.


1

Ви можете легко перевірити, чи рядок порожній за допомогою цього:

if ([yourstring isEqualToString:@""]) {
    // execute your action here if string is empty
}

1

Я перевірив порожню рядок, використовуючи код нижче:

//Check if we have any search terms in the search dictionary.
if( (strMyString.text==(id) [NSNull null] || [strMyString.text length]==0 
       || strMyString.text isEqual:@"")) {

   [AlertView showAlert:@"Please enter a valid string"];  
}


1
//Different validations:
 NSString * inputStr = @"Hey ";

//Check length
[inputStr length]

//Coming from server, check if its NSNull
[inputStr isEqual:[NSNull null]] ? nil : inputStr

//For validation in allowed character set
-(BOOL)validateString:(NSString*)inputStr
{
    BOOL isValid = NO;
    if(!([inputStr length]>0))
    {
        return isValid;

    }

    NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet characterSetWithCharactersInString:@".-"];
    [allowedSet formUnionWithCharacterSet:[NSCharacterSet decimalDigitCharacterSet]];
    if ([inputStr rangeOfCharacterFromSet:[allowedSet invertedSet]].location == NSNotFound)
    {
        // contains only decimal set and '-' and '.'

    }
    else
    {
        // invalid
        isValid = NO;

    }
    return isValid;
}

0

Ви можете мати порожній рядок двома способами:

1) @ "" // Не містить місця

2) @ "" // Містить простір

Технічно обидва рядки порожні. Ми можемо записати обидві речі просто за допомогою ONE Condition

if ([firstNameTF.text stringByReplacingOccurrencesOfString:@" " withString:@""].length==0)
{
    NSLog(@"Empty String");
}
else
{
    NSLog(@"String contains some value");
}

0

Спробуйте наступне

NSString *stringToCheck = @"";

if ([stringToCheck isEqualToString:@""])
{
   NSLog(@"String Empty");
}
else
{
   NSLog(@"String Not Empty");
}

-1
if(str.length == 0 || [str isKindOfClass: [NSNull class]]){
    NSLog(@"String is empty");
}
else{
    NSLog(@"String is not empty");
}    

1
Нульова перевірка повинна бути першою. str.lengthвикине виняток, якщо strце null.
Джеффі Томас

-2
if( [txtMobile.text length] == 0 )
{
    [Utility showAlertWithTitleAndMessage: AMLocalizedString(@"Invalid Mobile No",nil) message: AMLocalizedString(@"Enter valid Mobile Number",nil)];
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.