web-dev-qa-db-fra.com

Comment détecter si NSString est nul?

J'ai un morceau de code qui détecte si un NSString est NULL, nil, etc. Cependant, il se bloque. Voici mon code:

NSArray *resultstwo = [database executeQuery:@"SELECT * FROM processes WHERE ready='yes' LIMIT 0,1"];
for (NSDictionary *rowtwo in resultstwo) {

NSString *getCaption = [rowtwo valueForKey:@"caption"];

if (getCaption == NULL) {
theCaption = @"Photo uploaded...";
} else if (getCaption == nil) {
theCaption = @"Photo uploaded...";
} else if ([getCaption isEqualToString:@""]) {
theCaption = @"Photo uploaded...";
} else if ([getCaption isEqualToString:@" "]) {
theCaption = @"Photo uploaded...";
}

}

Et voici l'erreur:

Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '-[NSNull isEqualToString:]: sélecteur non reconnu envoyé à l'instance 0x3eba63d4 '

Est-ce que je fais quelque chose de mal? Dois-je le faire d'une manière différente?

54
iosfreak

La valeur NULL pour les objets Objective-C (type id) est nil.

Alors que NULL est utilisé pour pointeurs C (tapez void *).

(Au final, les deux finissent par conserver la même valeur (0x0). Ils diffèrent cependant en type.)

Dans Objective-C :

  • nil (tout en minuscules) est un pointeur nul vers un objet Objective-C .
  • Nil (en majuscules) est un pointeur nul vers une classe Objective-C .
  • NULL (toutes les majuscules) est un pointeur nul vers autre chose ( pointeurs C , c'est-à-dire).
  • [NSNull null] est un singleton pour les situations où l'utilisation de nil n'est pas possible (ajout/réception de nil à/de NSArrays par exemple)

Dans Objective-C++ :

  • Toutes ces réponses , plus:
  • null (minuscule) ou nullptr ( C++ 11 ou version ultérieure ) est un pointeur nul vers les objets C++ .

Donc, pour comparer avec nil, vous devez soit comparer avec nil (ou NULL respectivement) explicitement :

if (getCaption == nil) ...

ou laissez ObjC / [~ # ~] c [~ # ~] le faire implicitement pour vous:

if (!getCaption) ...

Cela fonctionne comme chaque expression dans [~ # ~] c [~ # ~] (et avec Objective-C étant un sur-ensemble de celui-ci) a une valeur booléenne implicite:

expression != 0x0 => true
expression == 0x0 => false

Maintenant, lors de la vérification de NSNull, cela ne fonctionnerait évidemment pas comme [NSNull null] renvoie un pointeur sur une instance singleton de NSNull, et non nil, et par conséquent, il n'est pas égal à 0x0.

Donc, pour comparer avec NSNull on peut utiliser:

if ((NSNull *)getCaption == [NSNull null]) ...

ou (préféré, voir commentaires):

if ([getCaption isKindOfClass:[NSNull class]]) ...

Gardez à l'esprit que ce dernier (en utilisant un appel de message) renverra false si getCaption se trouve être nil, ce qui, bien que formellement correct, pourrait ne pas être ce que vous attendez/vouloir.

Par conséquent, si l'un (pour une raison quelconque) devait comparer les deux nil/NULL et NSNull, il faudrait combiner ces deux vérifications:

if (!getCaption || [getCaption isKindOfClass:[NSNull class]]) ...

Pour obtenir de l'aide sur la formation de contrôles positifs équivalents , voir lois de De Morgan et négation booléenne .

Edit: NSHipster.com vient de publier un excellent article sur les différences subtiles entre zéro, nul, etc.

168
Regexident

Tu devrais utiliser

if ([myNSString isEqual:[NSNull null]])

Cela vérifiera si l'objet myNSString est égal à l'objet NSNull.

24
ludesign

La manière préférée de vérifier le NSNULL est

if(!getCaption || [getCaption isKindOfClass:[NSNull class]])   
6
Aadi007
if([getCaption class] == [NSNull class])
    ...

Vous pouvez aussi faire

if([getCaption isKindOfClass:[NSNull class]])
    ...

si vous voulez être à l'épreuve du temps contre de nouvelles sous-classes de NSNull.

2
Dustin

Vérifiez simplement avec ce code:

NSString *object;

if(object == nil)

Cela devrait fonctionner.

2
Surjeet Rajput