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'instance0x3eba63d4
'
Est-ce que je fais quelque chose de mal? Dois-je le faire d'une manière différente?
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 NSArray
s par exemple)Dans Objective-C++ :
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.
Tu devrais utiliser
if ([myNSString isEqual:[NSNull null]])
Cela vérifiera si l'objet myNSString est égal à l'objet NSNull.
La manière préférée de vérifier le NSNULL
est
if(!getCaption || [getCaption isKindOfClass:[NSNull class]])
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.
Vérifiez simplement avec ce code:
NSString *object;
if(object == nil)
Cela devrait fonctionner.