Ich muss überprüfen, ob ein Diktat einen Schlüssel hat oder nicht. Wie?
NSDictionarybeliebige Taste (unspezifisch) enthält , sollten Sie verwenden , [dictionary allKeys].count == 0wenn die countist 0es keine Tasten in der sind NSDictionary.
Ich muss überprüfen, ob ein Diktat einen Schlüssel hat oder nicht. Wie?
NSDictionarybeliebige Taste (unspezifisch) enthält , sollten Sie verwenden , [dictionary allKeys].count == 0wenn die countist 0es keine Tasten in der sind NSDictionary.
Antworten:
objectForKey gibt nil zurück, wenn kein Schlüssel existiert.
[NSNull null]stattdessen verwenden.
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
oder
if ([dictionary objectForKey:key]) {
// contains object
}
Neuere Versionen von Objective-C und Clang haben hierfür eine moderne Syntax:
if (myDictionary[myKey]) {
}
Sie müssen nicht auf Gleichheit mit nil prüfen, da nur Objective-C-Objekte ungleich nil in Wörterbüchern (oder Arrays) gespeichert werden können. Und alle Objective-C-Objekte sind wahrheitsgemäße Werte. Auch @NO, @0und [NSNull null]bewertet , wie wahr.
Edit: Swift ist jetzt eine Sache.
Für Swift würden Sie so etwas wie das Folgende versuchen
if let value = myDictionary[myKey] {
}
Diese Syntax führt den if-Block nur aus, wenn sich myKey im Diktat befindet und wenn dies der Fall ist, wird der Wert in der Wertvariablen gespeichert. Beachten Sie, dass dies auch für Falsey-Werte wie 0 funktioniert.
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}
Bei Verwendung von JSON-Wörterbüchern:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
Ich mag Fernandes 'Antwort, obwohl Sie zweimal nach dem Objekt fragen.
Dies sollte auch funktionieren (mehr oder weniger dasselbe wie Martins A).
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
}
Martins und diese Antwort funktionieren beide auf dem iPad2 iOS 5.0.1 9A405
Ein sehr böses Problem, das nur ein wenig Zeit mit dem Debuggen verschwendet hat - Sie werden möglicherweise durch die automatische Vervollständigung aufgefordert, zu versuchen, doesContaindas zu verwenden, was zu funktionieren scheint.
Ausgenommen, doesContainverwendet einen ID-Vergleich anstelle des von verwendeten Hash-Vergleichs. objectForKeyWenn Sie also ein Wörterbuch mit Zeichenfolgenschlüsseln haben, wird NO an a zurückgegeben doesContain.
NSMutableDictionary* keysByName = [[NSMutableDictionary alloc] init];
keysByName[@"fred"] = @1;
NSString* 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
Ja. Diese Art von Fehlern ist sehr häufig und führt zum Absturz der App. Also füge ich NSDictionary in jedem Projekt wie folgt hinzu:
//.h Dateicode:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
//.m Dateicode ist wie folgt
#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
Im Code können Sie wie folgt verwenden:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
So überprüfen Sie das Vorhandensein eines Schlüssels in NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Da nil nicht in Foundation-Datenstrukturen gespeichert werden kann, muss NSNullmanchmal a dargestellt werden nil. Da NSNulles sich um ein Singleton-Objekt handelt, können Sie NSNullmithilfe des direkten Zeigervergleichs überprüfen, ob der Wert im Wörterbuch gespeichert ist:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNullInstanz als Wert für den Schlüssel im Wörterbuch gespeichert wurde @"myKey". Das ist eine ganz andere Sache als der Schlüssel, der @"myKey"nicht im Wörterbuch enthalten ist - tatsächlich schließen sich die beiden gegenseitig aus.
Lösung für schnelle 4.2
Wenn Sie also nur die Frage beantworten möchten, ob das Wörterbuch den Schlüssel enthält, fragen Sie:
let keyExists = dict[key] != nil
Wenn Sie den Wert möchten und wissen, dass das Wörterbuch den Schlüssel enthält, sagen Sie:
let val = dict[key]!
Wenn Sie jedoch wie gewöhnlich nicht wissen, dass der Schlüssel enthalten ist - Sie möchten ihn abrufen und verwenden, aber nur, wenn er vorhanden ist -, verwenden Sie Folgendes if let:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}
Ich würde vorschlagen, dass Sie das Ergebnis der Suche in einer temporären Variablen speichern, testen, ob die temporäre Variable Null ist, und sie dann verwenden. Auf diese Weise suchen Sie nicht zweimal dasselbe Objekt nach:
id obj = [dict objectForKey:@"blah"];
if (obj) {
// use obj
} else {
// Do something else
}
Wie Adirael vorgeschlagen hat objectForKey, die Schlüsselexistenz zu überprüfen, aber wenn Sie objectForKeyein nullbares Wörterbuch aufrufen , stürzt die App ab, sodass ich dies auf folgende Weise behoben habe.
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;
if (dictionary && (object != [NSNull null])) {
self.name = [dictionary objectForKey:@"name"];
self.age = [dictionary objectForKey:@"age"];
}
return self;
}}
if ([MyDictionary objectForKey:MyKey]) {
// "Key Exist"
}