Je dois vérifier si un dict a une clé ou non. Comment?
objectForKey
renvoie nil si une clé n’existe pas.
if ([[dictionary allKeys] containsObject:key]) { // contains key }
ou
if ([dictionary objectForKey:key]) { // contains object }
Les versions plus récentes d’Objective-C et de Clang ont une syntaxe moderne pour cela:
if (myDictionary[myKey]) { }
Vous n’avez pas besoin de vérifier l’égalité avec nil, car seuls les objects Objective-C non nuls peuvent être stockés dans des dictionnaires (ou des tableaux). Et tous les objects Objective-C sont des valeurs véridiques. Même @NO
, @0
et [NSNull null]
considérés comme vrais.
Edit: Swift est maintenant une chose.
Pour Swift, vous essayez quelque chose comme ce qui suit
if let value = myDictionary[myKey] { }
Cette syntaxe exécutera uniquement le bloc if si myKey se trouve dans le dict et si c’est le cas, la valeur est stockée dans la variable value. Notez que cela fonctionne même pour des valeurs de fausse note telles que 0.
if ([mydict objectForKey:@"mykey"]) { // key exists. } else { // ... }
Lors de l’utilisation de dictionnaires JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]] if( isNull( dict[@"my_key"] ) ) { // do stuff }
J’aime la réponse de Fernandes même si vous demandez deux fois l’obj.
Cela devrait également faire (plus ou moins le même que celui de Martin).
id obj; if ((obj=[dict objectForKey:@"blah"])) { // use obj } else { // Do something else like creating the obj and add the kv pair to the dict }
Martin’s et cette réponse travaillent tous deux sur iPad2 iOS 5.0.1 9A405
Un très méchant gotcha qui a juste perdu un peu de temps à me déboguer – vous vous retrouverez peut-être incité par auto-complete à essayer doesContain
qui semble fonctionner.
Sauf que doesContain
utilise une comparaison id au lieu de la comparaison de hachage utilisée par objectForKey
donc si vous avez un dictionnaire avec des clés de chaîne, il renverra NO à un doesContain
.
NSMutableDictionary* keysByName = [[NSMutableDictionary alloc] init]; keysByName[@"fred"] = @1; NSSsortingng* test = @"fred"; if ([keysByName objectForKey:test] != nil) NSLog(@"\nit works for key lookups"); // OK else NSLog(@"\nsod it"); if (keysByName[test] != nil) NSLog(@"\nit works for key lookups using indexed syntax"); // OK else NSLog(@"\nsod it"); if ([keysByName doesContain:@"fred"]) NSLog(@"\n doesContain works literally"); else NSLog(@"\nsod it"); // this one fails because of id comparison used by doesContain
Oui. Ce type d’erreurs est très courant et conduit à un crash d’application. J’utilise donc pour append NSDictionary dans chaque projet comme ci-dessous:
//.h code de fichier:
@interface NSDictionary (AppDictionary) - (id)objectForKeyNotNull : (id)key; @end
Le code de fichier //.m est comme ci-dessous
#import "NSDictionary+WKDictionary.h" @implementation NSDictionary (WKDictionary) - (id)objectForKeyNotNull:(id)key { id object = [self objectForKey:key]; if (object == [NSNull null]) return nil; return object; } @end
Dans le code, vous pouvez utiliser comme ci-dessous:
NSStrting *testSsortingng = [dict objectForKeyNotNull:@"blah"];
En utilisant Swift, ce serait:
if myDic[KEY] != nil { // key exists }
Pour vérifier l’existence d’une clé dans NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil) NSLog(@"Key Exists"); else NSLog(@"Key not Exists");
Parce que nil ne peut pas être stocké dans les structures de données Foundation, NSNull
doit parfois représenter un nil
. NSNull
étant un object singleton, vous pouvez vérifier si NSNull
est la valeur stockée dans le dictionnaire en utilisant la comparaison directe de pointeurs:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
Je vous suggère de stocker le résultat de la recherche dans une variable temporaire, de tester si la variable temporaire est nulle et de l’utiliser ensuite. De cette façon, vous ne regardez pas le même object deux fois:
id obj = [dict objectForKey:@"blah"]; if (obj) { // use obj } else { // Do something else }
if ([MyDictionary objectForKey:MyKey]) { // "Key Exist" }
Comme Adirael a suggéré objectForKey
pour vérifier l’existance de la clé, mais lorsque vous appelez objectForKey
dans le dictionnaire objectForKey
, l’application est objectForKey
et j’ai résolu ce objectForKey
de la manière suivante.
- (instancetype)initWithDictionary:(NSDictionary*)dictionary { id object = dictionary; if (dictionary && (object != [NSNull null])) { self.name = [dictionary objectForKey:@"name"]; self.age = [dictionary objectForKey:@"age"]; } return self;
}