Jak sprawdzić, czy ciąg jest pusty w Objective-C?

651

Jak sprawdzić, czy NSStringw Objective-C jest pusty?

Jamey McElveen
źródło

Odpowiedzi:

1156

Możesz sprawdzić, czy [string length] == 0. Spowoduje to sprawdzenie, czy jest to poprawny, ale pusty ciąg (@ ""), a także czy jest zerowy, ponieważ wywołanie lengthzerowego zwróci również 0.

Marc Charbonneau
źródło
12
Istnieje kilka bardzo rzadkich NSStrings, w których spowoduje to fałszywie ujemny wynik (mówiąc, że ciąg nie jest pusty, gdy ze względów praktycznych jest). Zastanów się @"\u200B"(składający się tylko ze znaku Unicode ZERO WIDTH SPACE . Wydrukowanie go spowoduje wydrukowanie 0 znaków (zweryfikuj za pomocą czcionki o stałej szerokości), ale string.length da 1. Istnieją inne znaki Unicode (takie jak CHARACTER WYMIANY OBIEKTU ), które zachowują się podobnie. Możesz uzyskaj to drugie podczas analizowania tekstu PDF
fzwo
43
@ fzwo nie jest dupkiem, ale teoretycznie nie daje fałszywego negatywu. Zachowuje się dokładnie tak , jak można się spodziewać. Twoja interpretacja tego, co ZERO WIDTH SPACEjest, tak naprawdę nie ma znaczenia, ponieważ @"\u200B" jest to jednak znak, więc jeśli przetestujesz, czy łańcuch jest pusty, powie, że nie jest tak, ponieważ jest w nim znak. Po prostu nie można go wydrukować zgodnie ze standardem Unicode.
bmeulmeester,
2
Oczywiście jest to technicznie poprawne, nie dyskutuję o tym. Chcę tylko ostrzec, że to może nie wykazywać zamierzonego lub oczekiwanego zachowania, dlatego napisałem „do celów praktycznych”. To zależy od zamierzonego znaczenia „pusty”.
fzwo
4
To nie jest fałszywy negatyw. „Miejsce o zerowej wartości” to znak Unicode, jak każdy inny. Po prostu „warto pamiętać”, jeśli ma to znaczenie dla Twojej aplikacji. (Świetne myślenie, fzwo!)
Fattie
2
Daj mi znać, jeśli się mylę, ale myślę, że może też pominąć część == 0 i dodać negację przed: ![string length]. Wydaje się bardziej czysty.
damirstuhec
126

Odpowiedź Marca jest poprawna. Ale skorzystam z okazji, aby dołączyć wskaźnik do uogólnionego Wila ShipleyaisEmpty , który udostępnił na swoim blogu :

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);
}
Matt G.
źródło
26
Jeśli chcesz, aby było to bardzo ogólne, można zaimplementować tę logikę jako kategorię w NSObject zamiast używać metody statycznej, jak pokazano tutaj.
Brad The App Guy
16
Co dziwne, to tak naprawdę nie sprawdza [NSNull null].
Peter N Lewis
14
Jeśli jesteś w sytuacji, w której nie wiesz, jaki typ obiektu sprawdzasz, myślę, że to działa. Sugeruję jednak, że jeśli nie wiesz, czy obiekt to NSData czy NSArray, masz większe problemy. Jakie będzie twoje następne makro po tym wywołaniu, condenseToSingleNSData (id sprawa)? expandToNSArray (id rzecz)? Wcześniej czy później będziesz pytał, z jaką klasą masz do czynienia, lepiej zrobić to za pierwszym razem.
Brane,
1
@BradSmith, można utworzyć dla niego kategorię, ale wartości zerowe nie będą liczone, ponieważ metoda nie zostanie wywołana. Na przykład, jeśli rzecz = zero, [rzecz IsEmpty] nie zostanie wywołana i zawsze zwróci wartość false / NO. Aby sprawdzić zero, musi istnieć parametr. Żadne obiekty nie mogą się porównywać jako zero przez kategorię.
Chris
3
@chris, możesz zmienić metodę kategorii na -isNotEmpty:)
nielsbot,
93

Pierwsze podejście jest poprawne, ale nie działa, jeśli łańcuch zawiera puste spacje ( @" "). Więc musisz wyczyścić te białe przestrzenie przed przetestowaniem.

Ten kod usuwa wszystkie puste spacje po obu stronach łańcucha:

[stringObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];

Jednym dobrym pomysłem jest utworzenie jednego makra, więc nie musisz wpisywać tej linii potworów:

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

Teraz możesz użyć:

NSString *emptyString = @"   ";

if ( [allTrim( emptyString ) length] == 0 ) NSLog(@"Is empty!");
Zespół programistów SEQOY
źródło
3
Po co używać makr, gdy nie są one konieczne? W takim przypadku bezpieczeństwo wszelkiego rodzaju jest poświęcane bez żadnej realnej korzyści.
EM
Jest dla wygody, jeśli chcesz napisać „[object stringObject stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]„ za każdym razem, gdy chcesz sprawdzić, czy jeden ciąg jest pusty, zależy od Ciebie.
Zespół programistów SEQOY
18
lepiej byłoby, gdyby NSStringkategoria dodała nazwaną metodę, trimmedStringktóra robi dokładnie to, co napisałeś.
Dave DeLong,
2
Pamiętaj, że Apple whitespaceCharacterSetnie zawiera nowych linii! Oto kategoria, którą napisałem, w tym trimkilka innych przydatnych metod: github.com/alexch/unsuck/blob/master/unsuck/NSString%2BUnsuck.m github.com/alexch/unsuck/blob/master/unsuckTests/...
AlexChaffee
@EM Nie jestem fanem makr, ale nie rozumiem twoich obaw dotyczących bezpieczeństwa typu. Podczas kompilacji makro jest zastępowane jego zawartością, więc jeśli wywołasz makro z czymś innym niż NSString, nadal otrzymasz wiadomość od kompilatora. Kategorie i tak byłyby znacznie lepsze.
Zmaster
32

Jednym z najlepszych rozwiązań, jakie kiedykolwiek widziałem (lepszym niż Matt G), jest ta ulepszona funkcja wbudowana, którą wybrałem w niektórych repozytoriach Git Hub (jedno Wil Wadley, ale nie mogę znaleźć linku):

// 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);
}
Obrabować
źródło
2
To dzieło Wil Shipleya. Do twojej wiadomości, możesz zmienić [rzecz jestKindOfClass: [klasa NSNull]] na po prostu (rzecz == [NSNull null])
Steve N
Uff .... dokładnie tego szukałem. Oszalałem, próbując dowiedzieć się, dlaczego moja funkcja „cellForRowAtIndexPath” ulegała awarii z powodu ciągów zerowych (i nie mogłem złapać problemu). Ta funkcja rozwiązała to doskonale.
Mike Gledhill
Kopia komentarza @Brane: Jeśli jesteś w sytuacji, gdy nie wiesz, jaki typ obiektu sprawdzasz, myślę, że to działa. Sugeruję jednak, że jeśli nie wiesz, czy obiekt to NSData czy NSArray, masz większe problemy. Jakie będzie Twoje następne makro po tej rozmowie condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Wcześniej czy później będziesz pytał, z jaką klasą masz do czynienia, lepiej zrobić to za pierwszym razem.
Cœur
16

Lepiej skorzystaj z tej kategorii:

@implementation NSString (Empty)

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

@end
Cœur
źródło
6
Definicja ta prowadziłaby do wniosku, że ciąg „/ r / n / r / n” jest pusty, jeśli wyraźnie nie jest - zawiera białe znaki. Twoja funkcja to naprawdę: - (BOOL) isWhitespace (NSString *);
JBRWilkinson
6
Następstwem tego. Zaimplementowałem tę kategorię i jest pewien zwrot. Jeśli wywołasz to na łańcuch zerowy, ta funkcja nigdy nie zostanie wywołana, a otrzymasz wartość NIE (lub to, co zwraca wartość NIE) jako wartość zwracaną. Więc myślisz, że nie jest pusty ... To może zadziałać, jeśli nazwa to Filled lub coś w tym stylu.
Ying
Chyba właściwa kategoria byłaby wtedy: @implementation NSString (Empty) - (BOOL) empty{ return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]length] == 0); } @end jako kombinacja odpowiedzi Marca i Kyle'a.
palme
12

Kładę to:

@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

Problem polega na tym, że jeśli self jest zero, funkcja ta nigdy nie jest wywoływana. Zwróci false, co jest pożądane.

użytkownik4951
źródło
najlepszym rozwiązaniem, ponieważ a) jest metodą instancji ib) kategorią c) zero w sobie jest obsługiwane przez 'isNotEmpty' Thx!
Denis
Świetny pomysł, szkoda, -(BOOL)isEmpty{ return ![self isNotEmpty]}że nie działa na kategorię.
Alston,
Kopia komentarza @Brane: Jeśli jesteś w sytuacji, gdy nie wiesz, jaki typ obiektu sprawdzasz, myślę, że to działa. Sugeruję jednak, że jeśli nie wiesz, czy obiekt to NSData czy NSArray, masz większe problemy. Jakie będzie Twoje następne makro po tej rozmowie condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Wcześniej czy później będziesz pytał, z jaką klasą masz do czynienia, lepiej zrobić to za pierwszym razem.
Cœur
11

Inną opcją jest sprawdzenie, czy jest równe @""z isEqualToString:podobnym:

if ([myString isEqualToString:@""]) {
    NSLog(@"myString IS empty!");
} else {
    NSLog(@"myString IS NOT empty, it is: %@", myString);
}
chown
źródło
11

Po prostu przekaż swój ciąg do następującej metody:

+(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;
}
Mani
źródło
Sprawdź komentarze na stackoverflow.com/questions/21605075/…, dlaczego tak się nie dzieje. Jak to jest lepsze niż inne odpowiedzi tutaj.
Popeye
6

Wystarczy użyć jednego z poniższych if elsewarunków:

Metoda 1:

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

Metoda 2:

if ([yourString length] == 0) {
    // Empty yourString
} else {
    // yourString is not empty
}
Samir Jwarchan
źródło
6

Szybka wersja

Mimo że jest to pytanie Celu C, musiałem użyć go NSStringw Swift, więc w tym miejscu również zamieszczę odpowiedź.

let myNSString: NSString = ""

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

Lub jeśli NSStringjest opcjonalny:

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.")
    }
}

Normalna Stringwersja Swift to

let myString: String = ""

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

Zobacz także: Sprawdź pusty ciąg znaków w Swift?

Suragch
źródło
5

Być może ta odpowiedź jest duplikatem już udzielonych odpowiedzi, ale zrobiłem kilka modyfikacji i zmian w kolejności sprawdzania warunków. Proszę odnieść się do poniższego kodu:

+(BOOL)isStringEmpty:(NSString *)str
    {
        if(str == nil || [str isKindOfClass:[NSNull class]] || str.length==0) {
            return YES;
       }
        return NO;
    }
iDevAmit
źródło
To kategoria, którą możesz zobaczyć tutaj: goo.gl/bRcfn7 . Podoba mi się pomysł kategorii do tego
Daniel Gomez Rico
Nie, nie możemy powiedzieć, że to kategoria. Jeśli ta funkcja jest zaimplementowana w kategorii klasy NSString, to jest to kategoria. W przeciwnym razie możemy wywołać tę metodę z nazwą klasy, gdziekolwiek ją zaimplementowaliśmy. Podobnie jak Bool isEmptyStr = [MyClassName isStringEmpty: str] Ale i tak będzie lepiej, jeśli zadeklarujemy to w kategorii. Ponieważ w jakiś sposób musimy również skorzystać z kategorii.
iDevAmit
4

Za pomocą tej metody możesz sprawdzić, czy Twój łańcuch jest pusty, czy nie.

+(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;
}

Najlepszą praktyką jest, aby wspólna klasa mówiła UtilityClass i reklamowała tę metodę, abyś mógł skorzystać z tej metody, po prostu wywołując ją w aplikacji.

Fatima Arshad
źródło
4

Masz 2 metody sprawdzenia, czy ciąg jest pusty, czy nie:

Załóżmy, że twoja nazwa łańcucha to NSString *strIsEmpty.

Metoda 1:

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

else
{
    //String is not empty
}

Metoda 2:

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

else
{
    //String is not empty
}

Wybierz dowolną z powyższych metod i dowiedz się, czy ciąg znaków jest pusty, czy nie.

Aditya
źródło
3

Wystarczy sprawdzić długość sznurka

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

wiadomość do NIL zwróci zero lub 0, więc nie ma potrzeby testowania na zero :).

Miłego kodowania ...

Aks
źródło
Używałem tego wiele razy. Absolutnie nie ma potrzeby rozszerzeń, kategorii i co nie.
pnizzle
2

Działa jak dla mnie urok

Jeśli tak NSStringjests

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

    NSLog(@"s is empty");

} else {

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

}
MaxEcho
źródło
2

Poza podstawową koncepcją sprawdzania długości łańcucha mniejszej niż 1, ważne jest głębokie rozważenie kontekstu. Języki ludzkie lub komputerowe lub w inny sposób mogą mieć różne definicje pustych ciągów znaków i w tych samych językach dodatkowy kontekst może dodatkowo zmienić znaczenie.

Powiedzmy, że pusty ciąg oznacza „ciąg, który nie zawiera żadnych znaczących znaków w bieżącym kontekście”.

Może to oznaczać wizualnie, ponieważ kolor i kolor tła są takie same w przypisywanym ciągu. Skutecznie pusty.

Może to oznaczać brak znaczących znaków. Wszystkie kropki, wszystkie myślniki lub wszystkie podkreślenia można uznać za puste. Ponadto brak znaczących znaczących znaków może oznaczać ciąg, który nie zawiera znaków, które czytelnik rozumie. Mogą to być znaki w języku lub zestawie znaków zdefiniowane jako nieistotne dla czytelnika. Moglibyśmy zdefiniować to nieco inaczej, mówiąc, że ciąg znaków nie zna znanych słów w danym języku.

Można powiedzieć, że pusty jest funkcją procentu ujemnej przestrzeni w renderowanych glifach.

Nawet ciąg znaków niedrukowalnych bez ogólnej reprezentacji wizualnej nie jest naprawdę pusty. Przychodzą mi na myśl postacie kontrolne. Zwłaszcza niski zakres ASCII (dziwię się, że nikt nie wspomniał o nich, ponieważ łączą wiele systemów i nie są spacjami, ponieważ zwykle nie mają glifów ani wskaźników wizualnych). Jednak długość łańcucha nie jest równa zero.

Wniosek. Sama długość nie jest tu jedyną miarą. Przynależność do zestawu kontekstowego jest również bardzo ważna.

Członkostwo w zestawie znaków jest bardzo ważnym wspólnym dodatkowym środkiem. Znaczące sekwencje są również dość powszechne. (pomyśl SETI lub krypto lub captchas) Istnieją również dodatkowe abstrakcyjne zestawy kontekstów.

Zastanów się więc, zanim łańcuch będzie pusty tylko na podstawie długości lub białych znaków.

uchuugaka
źródło
2

Bardzo przydatny post, aby dodać obsługę NSDictionary, a także jedną małą zmianę

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);
}
Zeev Vax
źródło
Kopia komentarza @Brane: Jeśli jesteś w sytuacji, gdy nie wiesz, jaki typ obiektu sprawdzasz, myślę, że to działa. Sugeruję jednak, że jeśli nie wiesz, czy obiekt to NSData czy NSDictionary, masz większe problemy. Jakie będzie Twoje następne makro po tej rozmowie condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Wcześniej czy później będziesz pytał, z jaką klasą masz do czynienia, lepiej zrobić to za pierwszym razem.
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;
}
Ptbaileys
źródło
1
Pierwsze trzy warunki są zbędne i nie stringByStrippingWhitespace
podałeś
2

Najlepszym sposobem jest użycie kategorii.
Możesz sprawdzić następującą funkcję. Który ma wszystkie warunki do sprawdzenia.

-(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;
    }
Tarun
źródło
1

W każdym przypadku najlepszym sposobem jest sprawdzenie długości podanego ciągu. W tym przypadku, jeśli ciąg ma ciąg myString, kod jest następujący:

    int len = [myString length];
    if(len == 0){
       NSLog(@"String is empty");
    }
    else{
      NSLog(@"String is : %@", myString);
    }
AJS
źródło
1
if (string.length == 0) stringIsEmpty;
InvertedHeli
źródło
1

Sprawdź to :

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

Lub

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

Mam nadzieję, że to pomoże.

Mayur
źródło
1

Za pomocą tego możesz łatwo sprawdzić, czy ciąg znaków jest pusty:

if ([yourstring isEqualToString:@""]) {
    // execute your action here if string is empty
}
użytkownik3213914
źródło
1

Sprawdziłem pusty ciąg za pomocą poniższego kodu:

//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"];  
}
Jayprakash Dubey
źródło
1

To tak proste jak if([myString isEqual:@""])lubif([myString isEqualToString:@""])

Ahsan Ebrahim
źródło
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;
}
Rohit Kashyap
źródło
0

Możesz mieć pusty ciąg na dwa sposoby:

1) @ "" // Nie zawiera spacji

2) @ "" // Zawiera spację

Technicznie oba ciągi są puste. Obie rzeczy możemy napisać tylko za pomocą JEDNEGO warunku

if ([firstNameTF.text stringByReplacingOccurrencesOfString:@" " withString:@""].length==0)
{
    NSLog(@"Empty String");
}
else
{
    NSLog(@"String contains some value");
}
Chetan Rajauria
źródło
0

Spróbuj wykonać następujące czynności

NSString *stringToCheck = @"";

if ([stringToCheck isEqualToString:@""])
{
   NSLog(@"String Empty");
}
else
{
   NSLog(@"String Not Empty");
}
Rich Allen
źródło
-1
if(str.length == 0 || [str isKindOfClass: [NSNull class]]){
    NSLog(@"String is empty");
}
else{
    NSLog(@"String is not empty");
}    
C_compnay
źródło
1
Kontrola zerowa musi być pierwsza. str.lengthwyrzuci wyjątek, jeśli strjest pusty.
Jeffery Thomas
-2
if( [txtMobile.text length] == 0 )
{
    [Utility showAlertWithTitleAndMessage: AMLocalizedString(@"Invalid Mobile No",nil) message: AMLocalizedString(@"Enter valid Mobile Number",nil)];
}
Mohsin Sabasara
źródło