Pregunta

Tengo una clase que uso para configurar objetos en una matriz. En esta clase tengo un '' initWithDictionary '' personalizado, donde analizo un diccionario JSON . Sin embargo, como me encuentro con NSNull , esto bloquea mi aplicación. Para evitar esto, configuré una clase que maneja las excepciones, por lo que cuando una cadena es NSNull , se reemplaza con @ " " . o -1 para enteros.

Esta es mi clase NullExtensions:

@interface NSNull (valueExtensions)

-(int)intValue;
-(NSString *)stringValue;

@end

@implementation NSNull (valueExtensions)

-(int)intValue {
    return -1;
}

-(NSString*)stringValue {
    return @"";
}

@end

Sin embargo, en mi método initWithDictionary, el siguiente código bloquea mi aplicación:

self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];

No funciona independientemente de que el objeto en el diccionario analizado sea NSNull o que contenga una cadena válida. Solo si hago lo siguiente (y la cadena no es nula):

self.bookTitle = [parsedDictionary objectForKey:@"book_title"];

¿Es stringValue incorrecto en este caso? Y si es así, ¿cómo lo uso correctamente para configurar los reemplazos NSNull adecuados?

Thx

¿Fue útil?

Solución

En lugar de crear categorías en NSNull , para lo cual también tendría que agregar una categoría similar a NSString (es por eso que se bloquea, porque las cadenas reales no responden a stringValue): en su lugar, intente crear una categoría auxiliar en NSDictionary como " stringForKey " que usa el código que Johan publicó y devuelve un NSString , probablemente también debería exigir que todos los demás tipos se asignen a cadenas vacías también.

Otros consejos

Realmente realmente no desea agregar una categoría a NSNull que agregue métodos tan comunes. Eso cambiará el comportamiento de NSNull para las todas instancias de la aplicación, incluidas las creadas por los marcos subyacentes únicamente para su uso privado.

Si necesita una clase de valor que represente la noción de " value no existe y, por lo tanto, voy a devolver estos valores predeterminados " ;, crear una clase o instancia que represente exactamente eso.

En cuanto a por qué se bloquea, no podría decírtelo sin ver los detalles reales del accidente.


Y, sí, realmente es ESO malo agregar una categoría a una clase que agrega un método tan común. Todo lo que se necesita es un bit de código en un complemento o marco que lo haga:

if ([fooMaybeNull respondsToSelector: @selector(intValue)] bar = [fooMaybeNull intValue];

No es terriblemente descabellado: he tenido que depurar bloqueadores desagradables o comportamientos erróneos debido a exactamente este tipo de adición de categoría de willy-nilly.

Si va a agregar métodos a una clase a través de categorías, prefija los nombres de sus métodos para aislarlos de la funcionalidad existente . Todavía es frágil, pero manejable.

Las extensiones NSNull que ha escrito me parecen bien, pero usar un método como stringValue puede ser confuso ya que otras clases como NSNumber usan esto.

Personalmente, creo que el reemplazo de NSNull en este caso es innecesario. Si acaba de hacer una prueba rápida, puede reemplazar el NSNull donde lo necesite. por ejemplo,

id testObject = [parsedDictionary objectForKey:@"book_title"];
self.bookTitle = testObject==[NSNull null] ? @"" : testObject;

Está solicitando un NSString por su stringValue . No es necesario convertir una cadena en una cadena.

Prueba esto:

if (![[parsedDictionary objectForKey:@"book_title"] isKindOfClass:[NSNull class]]) {
    self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
} else {
    self.bookTitle = @"";
}

Editar: No debe usar la categoría en NSNull que creó. No lo necesitas, ni deberías quererlo. Si la fuente del diccionario inserta instancias NSNull , continúe y use mi código anterior. Normalmente, esperaría que simple no tenga ningún valor insertado para la clave, en ese momento puede ver si [parsedDictionary objectForKey: @ " book_title "] devuelve algo.

¿Está seguro de que el diccionario devuelve [NSNull null] ? De manera predeterminada, los diccionarios devuelven nil , no [NSNull null] , cuando no se encuentra un valor para una clave.

  

Sin embargo, en mi método initWithDictionary, el siguiente código bloquea mi aplicación:

self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];
  

No funciona independientemente de que el objeto en el diccionario analizado sea NSNull o que contenga una cadena válida.

Eso tiene sentido, ya que stringValue no es un método válido en NSString . Funcionará para NSValue y sus subclases, pero no para NSString .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top