Question

Je suis en train de créer une méthode qui vérifie pour un nul/nul/chaîne vide, et je vais essayer de le faire fonctionner comme une catégorie mais n'ayant aucune chance.

Je suis l'aide de ce code, basé sur les réponses à cette rubrique:

@implementation NSString (NSStringExtension)
- (BOOL)isNullOrEmpty {
    return self == nil || 
    self == (id)[NSNull null] ||
    [@"" isEqualToString:self] || 
    [[self stringByReplacingOccurrencesOfString:@" " withString:@""] length] == 0||
    [self isEqualToString:@"(null)"]
     || ([self respondsToSelector:@selector(length)] && [(NSData *) self length] == 0)
     || ([self respondsToSelector:@selector(count)] && [(NSArray *) self count] == 0)
     || [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
}
@end

Pourtant, quand j'essaie d'utiliser ce c'est ce que j'obtiens:

NSLog([@"" isNullOrEmpty] ? @"1":@"0"); // prints 1
NSString *s1 = nil;
NSLog([s1 isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([args.itemName isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? @"1":@"0"); // prints 0

C'est déconcertant de moi, et je ne peux que supposer qu'une certaine combinaison de iOS5/ARC est à l'origine du nil objet d'être contraint à une chaîne vide/pointeur.Le débogueur affiche la chaîne de caractères comme 0x0, mais lorsque j'utilise mon isNullOrEmpty méthode, j'obtiens la valeur false.

Était-ce utile?

La solution

return self == nil

Cela ne peut jamais arriver.Si vous essayez d'envoyer isNullOrEmpty (ou tout autre message) à nil, rien ne se passe (objc_msgSend(), la fonction de responsable de l'envoi de message, vérifie nil récepteur comme l'une des premières choses qu'il fait et s'interrompt).

self == (id)[NSNull null]

Cela permettra également de ne jamais arriver.Si vous envoyez isNullOrEmpty un objet est une instance de NSNull, votre méthode, qui est une méthode de NSString, ne sera pas appelé.Au lieu de cela, NSNull's version (qui n'existe pas) sera.

De même, ([self respondsToSelector:@selector(count)] && [(NSArray *) self count]) ne va jamais se produire.Si l'objet est un NSArray, puis isNullOrEmpty ne sera jamais exécuté, parce que, encore une fois, c'est une méthode de NSString.

En conséquence, [(NSData *) self length] ne pas faire ce que vous pensez que cela fonctionne. NSString les instances faire répondre à length, mais le casting de l'objet à NSData ne pas utiliser le NSData la version de la méthode, il finit toujours par le NSString la version de length, parce que l'objet est en fait un NSString (casting n'arrive qu'au moment de la compilation;il ne peut pas changer quoi que ce soit au moment de l'exécution).

[self isEqualToString:@"(null)"]

Ici vous semble être la vérification de nil encore une fois, mais vous sont induits en erreur par l' la représentation que NSLog choisit lors de l'impression nil:

NSLog(@"%@", nil);

Cette affiche (null) dans la console, mais cela ne signifie pas que l'objet lui-même est une chaîne de caractères avec les personnages. NSLog juste choisit cette chaîne à afficher pour nil.*

Plusieurs des choses que vous faites aurait besoin de cela pour être dans une catégorie sur NSObject, de sorte que la méthode serait en fait, même si l'objet n'était pas un NSString.

Pour rechercher une chaîne composée uniquement de blanc, tous vous avez besoin est la comparaison de chaîne de caractères vide @"" après le parage des espaces:

NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:@""];
// Or:
([trimmedSelf length] == 0);

*Et même, mieux faire NSLog(@"%@", [NSNull null]); affiche <null> (angle des crochets au lieu des parenthèses), merveilleusement déroutant les premières fois que vous rencontrez NSNull.

Autres conseils

Une autre approche peut consister à définir une macro simple.

#define NSStringIsNullOrEmpty(str) ((str==nil) || [(str) isEqualToString:@""])

C'est simple et efficace.Si vous n'aimez pas les macros, vous pouvez toujours convertir en un appel de fonction sans affecter le reste de votre code.

-- Mise à jour:

@Bryan a soulevé un bon point.Une fonction en ligne est un excellent moyen d'aller.Voici une mise à jour de macro qui permet d'évaluer str qu'une seule fois.

#define NSStringIsNullOrEmpty(str) ({ NSString *_str=(str); ((tmp==nil) || [tmp isEqualToString:@""]);})

En Objective-C, l'envoi d'un message à néant retourne toujours 0 (ou NO, une remise à zéro-out struct, NULL, etc., selon la déclaration de type de retour).L' isNullOrEmpty la méthode que vous avez écrit ne sera pas réellement être invoquée lorsque vous envoyez isNullOrEmpty pour nil.Voir la accepté de répondre à Envoyer un message à néant? pour plus d'informations.

Peut-être que vous pouvez changer votre méthode isNotNullOrEmpty.Ensuite, une valeur de retour de 0 lors de l'envoi isNotNullOrEmpty pour nil va donner un sens.

Vous n'êtes pas à l'appel de votre méthode, mais envoyer un message à néant.

Ce comportement est normal.Vous envoyez un message à nil après tout.Donc, il est de retour soit à zéro (ou une autre valeur 0).Qui les courts-circuits pour de faux, de sorte que " 0 " est imprimé dans le cas illustré ci-dessous:

NSLog([s1 isNullOrEmpty] ? @"1":@"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? @"1":@"0"); // prints 0

Vous pouvez confirmer votre message n'est pas appelée pour les cas en définissant un point d'arrêt dans votre nouvelle catégorie de méthode.

Comme d'autres l'ont dit, appelant [nil isNullOrEmpty]; ne sera pas réellement exécuter votre méthode.L' nil l'objet est juste que :vide lui-même.

Comme une solution, je tiens à dire que ce n'est pas parce que vous êtes dans un langage Orienté-Objet que vous ne devez jamais utiliser les fonctions.

BOOL IsStringNilOrEmpty(NSString*)str
{
    return str == nil ||
        str == null ||
        [@"" isEqualToString:str] ||
        [[str stringByReplacingOccurrencesOfString:@" " withString:@""] length] == 0||
        [str isEqualToString:@"(null)"]
        || ([str respondsToSelector:@selector(length)] && [(NSData *) str length] == 0)
        || ([str respondsToSelector:@selector(count)] && [(NSArray *) str count] == 0)
        || [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;   
}

en fait j'ai juste corrigé ce problème en le faisant tourner autour de lui comme si

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

ainsi, au lieu de isNullOrWhiteSpace c'est isNotNullOrWhiteSpace.

Voici ma méthode de vérification null/vide

-(NSString*)NULLInputinitWithString:(NSString*)InputString {

if( (InputString == nil) ||(InputString ==(NSString*)[NSNull null])||([InputString isEqual:nil])||([InputString length] == 0)||([InputString isEqualToString:@""])||([InputString isEqualToString:@"(NULL)"])||([InputString isEqualToString:@"<NULL>"])||([InputString isEqualToString:@"<null>"]||([InputString isEqualToString:@"(null)"])||([InputString isEqualToString:@"NULL"]) ||([InputString isEqualToString:@"null"])))

    return @"";
else
    return InputString ;

}

Avez-vous pensé à la création d'une méthode de classe, une catégorie qui s'étend NSString?

NSString+NSStringExtensions.h

#import <Foundation/Foundation.h>

@interface NSString(NSStringExtensions)
+(BOOL)isNilOrEmpty:(NSString*)string;
@end

NSString+NSStringExtensions.m

#import "NSString+NSStringExtensions.h"

@implementation NSString(NSStringExtensions)

+(BOOL)isNilOrEmpty:(NSString*)string
{
    if (nil == string)
    {
        return YES;
    }
    if (string.length == 0)
    {
        return YES;
    }
    return NO;
}

@end

Alors vous l'utiliser comme ceci:

#import "NSString+NSStringExtensions.h"
...
NSLog([NSString isNilOrEmpty:@""] ? @"1":@"0");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top