objective-c null touchjson

objective c - TouchJSON, tratando con NSNull



objective-c (3)

Hola, estoy usando TouchJSON para deserializar algunos JSON. Lo he estado usando en el pasado y en esas ocasiones traté las ocurrencias de NSNull manualmente. Pensaría que el autor también tenía que lidiar con esto, así que hacerlo de nuevo solo sería una sobrecarga. Entonces encontré esto en la documentación:

Evitando los valores NSNull en la salida.

NSData *theJSONData = /* some JSON data */ CJSONDeserializer *theDeserializer = [CJSONDeserializer deserializer]; theDeserializer.nullObject = NULL; NSError *theError = nil; id theObject = [theDeserializer deserialize:theJSONData error:&theError];}

Según entiendo, el usuario de la clase puede pasar un puntero nulo estilo C al deserializador y cuando encuentre un NSNull insertará los valores (NULL) que se le pasaron. Luego, cuando use los valores, no obtendré NSNull, sino NULL.

Esto parece extraño, el valor de retorno es un NSDictionary que solo puede contener Objetos, ¿no debería el valor predeterminado ser ''nil''?

Si es NULL, ¿puedo verificar los valores como este?

if([jsonDataDict objectForKey:someKey] == NULL)

Parecería más lógicamente poder hacer esto:

if(![jsonDataDict objectForKey:someKey])

No, para mencionar todos los casos en los que se permite pasar nulo, pero pasar NULL provoca un bloqueo.

¿O puedo simplemente pasar ''nil'' al deserializador?

Mucho de esto se debe a que todavía estoy luchando con nil, NULL, [NSNULL null], tal vez no esté viendo las posibles advertencias al usar nil.


Hay bibliotecas que se ocupan de ello. Uno de ellos es SwiftyJSON en Swift , otro es NSTEasyJSON en Objective-C . Con esta biblioteca (NSTEasyJSON) será fácil lidiar con tales problemas. En su caso, simplemente puede verificar los valores que necesita:

NSTEasyJSON *JSON = [NSTEasyJSON withData:JSONData]; NSString *someValue = JSON[someKey].string;

Este valor será NSString o nil y no debe verificarlo por NSNull, NULL usted mismo.


Para otra biblioteca JSON, pero con los mismos problemas, he creado la siguiente categoría en NSDictionary:

@implementation NSDictionary (Utility) // in case of [NSNull null] values a nil is returned ... - (id)objectForKeyNotNull:(id)key { id object = [self objectForKey:key]; if (object == [NSNull null]) return nil; return object; } @end

Cada vez que trato con datos JSON de dicha biblioteca, recupero valores como este:

NSString *someString = [jsonDictionary objectForKeyNotNull:@"SomeString"];

De esta manera, el código de mis proyectos se vuelve mucho más limpio y, al mismo tiempo, no tengo que pensar en tratar con valores [NSNull null] y similares.


nil y NULL son en realidad iguales a cero, por lo que son, en la práctica, intercambiables. Pero tiene razón, para mantener la coherencia, la documentación para TouchJSON debería haber utilizado theDeserializer.nullObject = nil lugar de NULL .

Ahora, cuando haces eso, tu segundo predicado realmente funciona bien:

if (![jsonDataDict objectForKey:someKey])

porque TouchJSON omite la clave del diccionario cuando tiene nullObject establecido en nil (o NULL ). Cuando la clave no existe en el diccionario, NSDictionary devuelve nil, que es cero, por lo que su condición if funciona como usted espera.

Si no especifica nullObject como nil , puede buscar null así:

if ([jsonDataDict objectForKey:someKey] == [NSNull null])