Comment vérifier si un NSDictionary ou NSMutableDictionary contient une clé?

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; 

}