objective how combine and objective-c foundation

objective-c - how - swift cocoa



¿Cómo verificar si un NSDictionary o NSMutableDictionary contiene una clave? (14)

Necesito comprobar si un dict tiene una llave o no. ¿Cómo?


Como Adirael sugirió objectForKey para verificar la existencia de la clave, pero cuando llama a objectForKey en un diccionario que puede objectForKey , la aplicación se objectForKey , por lo que lo arreglé de la siguiente manera.

- (instancetype)initWithDictionary:(NSDictionary*)dictionary { id object = dictionary; if (dictionary && (object != [NSNull null])) { self.name = [dictionary objectForKey:@"name"]; self.age = [dictionary objectForKey:@"age"]; } return self;

}


Cuando se usan diccionarios JSON:

#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]] if( isNull( dict[@"my_key"] ) ) { // do stuff }


Debido a que nil no se puede almacenar en las estructuras de datos de Foundation, NSNull veces representa un nil . Debido a que NSNull es un objeto singleton, puede verificar si NSNull es el valor almacenado en el diccionario mediante la comparación directa de punteros:

if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }


Las versiones más recientes de Objective-C y Clang tienen una sintaxis moderna para esto:

if (myDictionary[myKey]) { }

No es necesario verificar la igualdad con cero, ya que solo los objetos Objective-C que no sean nulos se pueden almacenar en diccionarios (o matrices). Y todos los objetos de Objective-C son valores de verdad. Incluso @NO , @0 y [NSNull null] evalúan como verdaderos.

Edit: Swift es ahora una cosa.

Para Swift intentarías algo como lo siguiente

if let value = myDictionary[myKey] { }

Esta sintaxis solo ejecutará el bloque if si myKey está en el dict y si lo está, el valor se almacena en la variable de valor. Tenga en cuenta que esto funciona incluso para valores falsey como 0.


Le sugiero que almacene el resultado de la búsqueda en una variable temporal, compruebe si la variable temporal es nula y luego la utilice. De esa manera no se ve el mismo objeto dos veces:

id obj = [dict objectForKey:@"blah"]; if (obj) { // use obj } else { // Do something else }


Me gusta la respuesta de Fernandes, aunque pides el obj dos veces.

Esto también debería hacer (más o menos lo mismo que A 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 y esta respuesta funcionan en iPad2 iOS 5.0.1 9A405


Para verificar la existencia de clave en NSDictionary:

if([dictionary objectForKey:@"Replace your key here"] != nil) NSLog(@"Key Exists"); else NSLog(@"Key not Exists");


Sí. Este tipo de errores son muy comunes y conducen a la caída de la aplicación. Así que uso para agregar NSDictionary en cada proyecto de la siguiente manera:

//.h código de archivo:

@interface NSDictionary (AppDictionary) - (id)objectForKeyNotNull : (id)key; @end

El código del archivo //.m es el siguiente

#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

En el código se puede utilizar de la siguiente manera:

NSStrting *testString = [dict objectForKeyNotNull:@"blah"];


Un error muy desagradable que solo desperdició un poco de mi tiempo en la depuración. Es posible que el autocompletar te pida que intentes usar doesContain que parece funcionar.

Excepto, doesContain utiliza una comparación de id en lugar de la comparación de hash utilizada por objectForKey por lo que si tiene un diccionario con claves de cadena, devolverá NO a la 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


Usando Swift, sería:

if myDic[KEY] != nil { // key exists }


objectForKey devolverá nil si no existe una clave.


if ([MyDictionary objectForKey:MyKey]) { // "Key Exist" }


if ([[dictionary allKeys] containsObject:key]) { // contains key }

o

if ([dictionary objectForKey:key]) { // contains object }


if ([mydict objectForKey:@"mykey"]) { // key exists. } else { // ... }