Comment puis-je tester si une chaîne est vide dans Objective-C?

651

Comment tester si un NSStringest vide dans Objective-C?

Jamey McElveen
la source

Réponses:

1156

Vous pouvez vérifier si [string length] == 0. Cela vérifiera s'il s'agit d'une chaîne valide mais vide (@ "") ainsi que si elle est nulle, car appeler lengthnil renverra également 0.

Marc Charbonneau
la source
12
Il existe des chaînes NSStrings très rares où cela entraînera un faux négatif (en disant que la chaîne n'est pas vide, alors que, pour des raisons pratiques, elle l'est). Considérez @"\u200B"(composé uniquement du caractère Unicode ZERO WIDTH SPACE . L'imprimer imprimera 0 caractères (vérifiez en utilisant la police à espacement fixe), mais string.length donnera 1. Il existe d'autres caractères Unicode (comme le OBJECT REPLACEMENT CHARACTER ) qui se comportent de la même manière. Vous pouvez obtenir ce dernier lors de l'analyse du texte PDF
fzwo
43
@fzwo ne doit pas être un âne, mais en théorie, cela ne donne pas un faux négatif. Il se comporte exactement comme vous vous y attendez. Votre interprétation de ce qui ZERO WIDTH SPACEest n'a pas vraiment d'importance, car @"\u200B" c'est quand même un caractère, donc si vous testez que la chaîne est vide, cela dira que ce n'est pas parce qu'il y a un caractère dedans. Il n'est tout simplement pas imprimable selon la norme Unicode.
bmeulmeester
2
Bien sûr, c'est techniquement correct, je ne discute pas de cela. Je veux juste vous avertir que cela peut ne pas présenter le comportement prévu ou attendu, c'est pourquoi j'ai écrit "à des fins pratiques". Cela dépend de la signification voulue de "vide".
fzwo
4
Ce n'est pas un faux négatif. Un "espace nul" est un caractère unicode comme les autres. Il est juste "intéressant de s'en souvenir" s'il est pertinent pour votre application. (Super pensée, fzwo!)
Fattie
2
Permettez - moi de savoir si je me trompe, mais je pense que vous pouvez aussi Omettre == 0 partie et ajouter une négation devant: ![string length]. Semble plus propre.
damirstuhec
126

La réponse de Marc est correcte. Mais je profite de l'occasion pour inclure un pointeur sur le général de Wil Shipley isEmpty, qu'il a partagé sur son blog :

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
la source
26
Si vous voulez que cela soit très généralisé, on pourrait implémenter cette logique en tant que catégorie sur NSObject au lieu d'utiliser une méthode statique comme indiqué ici.
Brad The App Guy
16
Curieusement, cela ne vérifie pas réellement [NSNull null].
Peter N Lewis
14
Si vous êtes dans une situation où vous ne savez pas quel type d'objet vous vérifiez, je suppose que cela fonctionne. Cependant, je suggère que si vous ne savez pas si un objet est NSData ou NSArray, vous avez de plus gros problèmes. Quelle sera votre prochaine macro après cet appel, condenseToSingleNSData (id thing)? expandToNSArray (id chose)? Tôt ou tard, vous vous demanderez à quel type de classe vous avez affaire, mieux vaut le faire sur la première référence.
Brane
1
@BradSmith, on pourrait lui créer une catégorie mais aucune valeur ne serait comptée car la méthode ne serait pas appelée. Par exemple, si thing = nil, [thing IsEmpty] ne serait pas appelé et retournerait toujours false / NO. Pour vérifier zéro, il doit y avoir un paramètre. Aucun objet ne peut se comparer à zéro via une catégorie.
Chris
3
@chris alors vous pouvez changer la méthode de catégorie en -isNotEmpty:)
nielsbot
93

La première approche est valide, mais ne fonctionne pas si votre chaîne contient des espaces vides ( @" "). Vous devez donc effacer ces espaces blancs avant de le tester.

Ce code efface tous les espaces vides des deux côtés de la chaîne:

[stringObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];

Une bonne idée est de créer une macro, vous n'avez donc pas à taper cette ligne monstre:

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

Vous pouvez maintenant utiliser:

NSString *emptyString = @"   ";

if ( [allTrim( emptyString ) length] == 0 ) NSLog(@"Is empty!");
Équipe de développement SEQOY
la source
3
Pourquoi utiliser des macros quand elles ne sont pas nécessaires? Dans ce cas, toute sécurité de type est sacrifiée sans aucun avantage réel.
EM
Est pour la commodité simple, si vous aimez écrire "[object stringObject stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]]" "chaque fois que vous voulez vérifier si une chaîne est vide, c'est à vous.
SEQOY Development Team
18
qui serait mieux servi par une NSStringcatégorie qui ajoute une méthode appelée trimmedStringqui fait exactement ce que vous avez écrit.
Dave DeLong
2
Notez qu'Apple whitespaceCharacterSetn'inclut pas de nouvelles lignes! Voici une catégorie que j'ai écrite, y compris trimet quelques autres méthodes utiles: github.com/alexch/unsuck/blob/master/unsuck/NSString%2BUnsuck.m github.com/alexch/unsuck/blob/master/unsuckTests/…
AlexChaffee
@EM Je ne suis pas un fan des macros, mais je ne comprends pas votre souci de sécurité de type. Pendant la compilation, la macro est remplacée par son contenu, donc si vous appelez la macro avec quelque chose de différent d'une NSString, vous obtenez toujours un message du compilateur. Les catégories seraient bien mieux de toute façon.
Zmaster
32

L'une des meilleures solutions que j'ai jamais vues (mieux que celle de Matt G) est cette fonction en ligne améliorée que j'ai choisie sur un dépôt Git Hub (celui de Wil Shipley, mais je ne trouve pas le lien):

// 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);
}
Rob
la source
2
C'est le travail de Wil Shipley. Pour info, vous pouvez changer [chose isKindOfClass: [classe NSNull]] en juste (chose == [NSNull null])
Steve N
Ouf .... exactement ce que je cherchais. J'étais devenu fou, essayant de comprendre pourquoi ma fonction "cellForRowAtIndexPath" plantait à cause de chaînes nulles (et je n'ai pas pu attraper le problème). Cette fonction l'a parfaitement résolu.
Mike Gledhill
Copie du commentaire @Brane: Si vous êtes dans une situation où vous ne savez pas quel type d'objet vous vérifiez, je suppose que cela fonctionne. Cependant, je suggère que si vous ne savez pas si un objet est NSData ou NSArray, vous avez de plus gros problèmes. Quelle sera votre prochaine macro après cet appel condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Tôt ou tard, vous vous demanderez à quel type de classe vous avez affaire, mieux vaut le faire sur la première référence.
Cœur
16

Vous devriez mieux utiliser cette catégorie:

@implementation NSString (Empty)

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

@end
Cœur
la source
6
Cette définition conclurait que la chaîne "/ r / n / r / n" est vide, alors qu'elle ne l'est clairement pas - elle contient des espaces. Votre fonction est vraiment: - (BOOL) isWhitespace (NSString *);
JBRWilkinson
6
Un corollaire à cela. J'ai implémenté cette catégorie, et il y a une torsion. Si vous appelez cela sur une chaîne nulle, cette fonction n'est jamais appelée et vous obtenez un NON (ou ce qui donne la valeur NON) comme valeur de retour. Ensuite, vous pensez qu'il n'est pas vide ... Cela pourrait fonctionner si le nom était isFilled ou quelque chose comme ça.
Ying
Je suppose que la bonne catégorie serait alors: @implementation NSString (Empty) - (BOOL) empty{ return ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]length] == 0); } @end comme une combinaison de la réponse de Marc et Kyle.
palme du
12

Je mets ceci:

@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

Le problème est que si self est nul, cette fonction n'est jamais appelée. Cela retournera faux, ce qui est souhaité.

user4951
la source
meilleure solution car a) est la méthode des instances et b) la catégorie c) le cas nul sur lui-même est géré par 'isNotEmpty' Thx!
Denis
Excellente idée, tout simplement dommage -(BOOL)isEmpty{ return ![self isNotEmpty]}ne fonctionnera pas sur la catégorie.
Alston
Copie du commentaire @Brane: Si vous êtes dans une situation où vous ne savez pas quel type d'objet vous vérifiez, je suppose que cela fonctionne. Cependant, je suggère que si vous ne savez pas si un objet est NSData ou NSArray, vous avez de plus gros problèmes. Quelle sera votre prochaine macro après cet appel condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Tôt ou tard, vous vous demanderez à quel type de classe vous avez affaire, mieux vaut le faire sur la première référence.
Cœur
11

Une autre option consiste à vérifier si elle est égale à @""avec isEqualToString:comme ceci:

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

Passez simplement votre chaîne à la méthode suivante:

+(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
la source
Consultez les commentaires sur stackoverflow.com/questions/21605075/… pour savoir pourquoi cela est faux. Aussi comment est-ce mieux que les autres réponses ici.
Popeye
6

Utilisez simplement l'une des if elseconditions ci-dessous:

Méthode 1:

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

Méthode 2:

if ([yourString length] == 0) {
    // Empty yourString
} else {
    // yourString is not empty
}
Samir Jwarchan
la source
6

Version Swift

Même s'il s'agit d'une question sur l'objectif C, je devais l'utiliser NSStringdans Swift, je vais donc également inclure une réponse ici.

let myNSString: NSString = ""

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

Ou s'il NSStrings'agit d'une option:

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

La Stringversion normale de Swift est

let myString: String = ""

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

Voir aussi: Vérifier la chaîne vide dans Swift?

Suragch
la source
5

Peut-être que cette réponse est le double des réponses déjà données, mais j'ai fait peu de modifications et de changements dans l'ordre de vérification des conditions. Veuillez vous référer au code ci-dessous:

+(BOOL)isStringEmpty:(NSString *)str
    {
        if(str == nil || [str isKindOfClass:[NSNull class]] || str.length==0) {
            return YES;
       }
        return NO;
    }
iDevAmit
la source
Il s'agit d'une catégorie, vous pouvez voir comment la créer ici: goo.gl/bRcfn7 . J'aime l'idée d'une catégorie pour ça
Daniel Gomez Rico
Non, nous ne pouvons pas dire que c'est une catégorie. Si cette fonction est implémentée sous la catégorie de la classe NSString, alors c'est la catégorie. Sinon, nous pouvons appeler cette méthode avec le nom de classe partout où nous l'avons implémentée. Comme Bool isEmptyStr = [MyClassName isStringEmpty: str] Mais quand même, ce sera mieux si nous le déclarons sous catégorie. Parce que d'une manière ou d'une autre, nous devons également profiter des catégories.
iDevAmit
4

Vous pouvez vérifier que votre chaîne est vide ou non en utilisant cette méthode:

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

La meilleure pratique est de faire dire à une classe partagée UtilityClass et d'annoncer cette méthode afin que vous puissiez utiliser cette méthode en l'appelant simplement dans votre application.

Fatima Arshad
la source
4

Vous avez 2 méthodes pour vérifier si la chaîne est vide ou non:

Supposons que votre nom de chaîne soit NSString *strIsEmpty .

Méthode 1:

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

else
{
    //String is not empty
}

Méthode 2:

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

else
{
    //String is not empty
}

Choisissez l'une des méthodes ci-dessus et apprenez si la chaîne est vide ou non.

Aditya
la source
3

Vérifiez simplement la longueur de votre chaîne

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

un message à NIL retournera nil ou 0, donc pas besoin de tester pour nil :).

Bon codage ...

Aks
la source
Je l'ai utilisé tant de fois. Absolument pas besoin d'extensions, de catégories, etc.
pnizzle
2

Cela fonctionne comme un charme pour moi

Si le NSStringests

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

    NSLog(@"s is empty");

} else {

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

}
MaxEcho
la source
2

Ainsi, outre le concept de base de vérification d'une longueur de chaîne inférieure à 1, il est important de considérer le contexte en profondeur. Les langues humaines ou informatiques ou autrement peuvent avoir des définitions différentes de chaînes vides et dans ces mêmes langues, un contexte supplémentaire peut encore changer la signification.

Disons qu'une chaîne vide signifie "une chaîne qui ne contient aucun caractère significatif dans le contexte actuel".

Cela pourrait signifier visuellement, car la couleur et la couleur d'arrière-plan sont les mêmes dans une chaîne attribuée. Effectivement vide.

Cela pourrait signifier vide de caractères significatifs. Tous les points ou tous les tirets ou tous les traits de soulignement peuvent être considérés comme vides. En outre, vide de caractères significatifs significatifs pourrait signifier une chaîne qui n'a pas de caractères que le lecteur comprend. Il peut s'agir de caractères dans une langue ou un jeu de caractères défini comme dépourvu de sens pour le lecteur. Nous pourrions le définir un peu différemment pour dire que la chaîne ne forme aucun mot connu dans une langue donnée.

On pourrait dire que vide est fonction du pourcentage d'espace négatif dans les glyphes rendus.

Même une séquence de caractères non imprimables sans représentation visuelle générale n'est pas vraiment vide. Les personnages de contrôle me viennent à l'esprit. Surtout la plage ASCII basse (je suis surpris que personne ne les ait mentionnés car ils utilisent de nombreux systèmes et ne sont pas des espaces car ils n'ont normalement pas de glyphes et pas de métriques visuelles). Pourtant, la longueur de la chaîne n'est pas nulle.

Conclusion. La longueur seule n'est pas la seule mesure ici. L'appartenance à un ensemble contextuel est également très importante.

L'appartenance au jeu de caractères est une mesure supplémentaire commune très importante. Les séquences significatives sont également assez courantes. (pensez SETI ou crypto ou captchas) Il existe également d'autres ensembles de contextes plus abstraits.

Réfléchissez donc bien avant de supposer qu'une chaîne n'est vide qu'en fonction de la longueur ou de l'espace.

uchuugaka
la source
2

Post très utile, pour ajouter un support NSDictionary ainsi qu'un petit changement

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
la source
Copie du commentaire @Brane: Si vous êtes dans une situation où vous ne savez pas quel type d'objet vous vérifiez, je suppose que cela fonctionne. Cependant, je suggère que si vous ne savez pas si un objet est NSData ou NSDictionary, vous avez de plus gros problèmes. Quelle sera votre prochaine macro après cet appel condenseToSingleNSData(id thing)? expandToNSArray(id thing)? Tôt ou tard, vous vous demanderez à quel type de classe vous avez affaire, mieux vaut le faire sur la première référence.
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
la source
1
Les trois premières conditions sont redondantes, et vous n'avez pas inclus la source destringByStrippingWhitespace
mattsven
2

La meilleure façon est d'utiliser la catégorie.
Vous pouvez vérifier la fonction suivante. Qui a toutes les conditions à vérifier.

-(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
la source
1

La meilleure façon dans tous les cas est de vérifier la longueur de la chaîne donnée. Pour cela, si votre chaîne est myString, le code est:

    int len = [myString length];
    if(len == 0){
       NSLog(@"String is empty");
    }
    else{
      NSLog(@"String is : %@", myString);
    }
AJS
la source
1
if (string.length == 0) stringIsEmpty;
InvertedHeli
la source
1

Vérifiez ça :

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

Ou

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

J'espère que cela vous aidera.

Mayur
la source
1

Vous pouvez facilement vérifier si la chaîne est vide avec ceci:

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

J'ai vérifié une chaîne vide en utilisant le code ci-dessous:

//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
la source
1

C'est aussi simple que if([myString isEqual:@""])ouif([myString isEqualToString:@""])

Ahsan Ebrahim
la source
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
la source
0

Vous pouvez avoir une chaîne vide de deux manières:

1) @ "" // Ne contient pas d'espace

2) @ "" // Contient de l'espace

Techniquement, les deux chaînes sont vides. Nous pouvons écrire les deux choses en utilisant UNE seule condition

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

Essayez ce qui suit

NSString *stringToCheck = @"";

if ([stringToCheck isEqualToString:@""])
{
   NSLog(@"String Empty");
}
else
{
   NSLog(@"String Not Empty");
}
Rich Allen
la source
-1
if(str.length == 0 || [str isKindOfClass: [NSNull class]]){
    NSLog(@"String is empty");
}
else{
    NSLog(@"String is not empty");
}    
C_compnay
la source
1
La vérification nulle doit être la première. str.lengthlèvera une exception si strest nul.
Jeffery Thomas
-2
if( [txtMobile.text length] == 0 )
{
    [Utility showAlertWithTitleAndMessage: AMLocalizedString(@"Invalid Mobile No",nil) message: AMLocalizedString(@"Enter valid Mobile Number",nil)];
}
Mohsin Sabasara
la source