2012-10-11 64 views
8

Actualmente estoy escribiendo una aplicación (Target iOS 6, ARC habilitado) que usa JSON para transmisión de datos y Core Data para almacenamiento persistente. Los datos JSON se generan a partir de una base de datos MySQL mediante un script PHP a través de json_encode.Resultados de NSJSONSerialization en EXC_BAD_ACCESS

mi problema es que con los datos de ciertas tablas el siguiente código falla:

- (NSDictionary *)executeFetch:(NSString *)query 
{ 
    NSURL *requesturl = [NSURL URLWithString:[query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 

    NSError *dataError = nil; 
    self.jsonData = [NSData dataWithContentsOfURL:requesturl options:kNilOptions error:&dataError]; 

    NSError *error = nil; 
    self.jsonSerializationResult = [NSJSONSerialization JSONObjectWithData:self.jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error]; 

    return self.jsonSerializationResult; 

} 

El programa siempre se bloquea con un error EXC_BAD_ACCESS en la línea donde dice self.jsonSerializationResult e Instrumentos dice que había un zombi detectado Sé que esto significa que algún objeto envío un mensaje a es nula, pero no puedo averiguar cómo solucionarlo ... Eso es lo que tiene que decir Instrumentos:

# Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller 
0 0xa1b8a70 CFString (mutable) Malloc 1 00:01.603.081 32 Foundation -[NSPlaceholderMutableString initWithBytesNoCopy:length:encoding:freeWhenDone:] 
1 0xa1b8a70 CFString (mutable) Release 0 00:01.603.137 0 Foundation newJSONValue 
2 0xa1b8a70 CFString (mutable) Zombie -1 00:01.603.259 0 Foundation newJSONString 

Mi programa trabaja con todos los JSON salida a excepción de éste:

{ 
    "termin":[ 
     { 
     "termin_id":"17", 
     "veranstaltung_id":"20", 
     "beginn":"2012-09-28 17:00:00", 
     "ende":"2012-09-28 18:00:00", 
     "freie_pl\u00e4tze":null 
     }, 
     { 
     "termin_id":"18", 
     "veranstaltung_id":"26", 
     "beginn":"2012-09-28 19:00:00", 
     "ende":"2012-09-28 20:00:00", 
     "freie_pl\u00e4tze":null 
     }, 
     { 
     "termin_id":"19", 
     "veranstaltung_id":"26", 
     "beginn":"2012-09-28 21:00:00", 
     "ende":"2012-09-28 22:00:00", 
     "freie_pl\u00e4tze":null 
     }, 
     { 
     "termin_id":"20", 
     "veranstaltung_id":"46", 
     "beginn":"2012-09-28 19:00:00", 
     "ende":"2012-09-28 20:00:00", 
     "freie_pl\u00e4tze":null 
     }, 
     { 
     "termin_id":"24", 
     "veranstaltung_id":"66", 
     "beginn":"2012-09-28 22:00:00", 
     "ende":"2012-09-28 22:30:00", 
     "freie_pl\u00e4tze":"120" 
     } 
    ] 
} 

pensé en algún posible error de origen pero ninguno parece ser la responsable:

  • jsonData o jsonSerializationResult podrían ser nula: no son
  • PHP generada JSON válido: comprobado para que con un validador
  • valores nulos: no es un problema con otras mesas

nadie tiene una idea?

Respuesta

11

Parece un error/defecto con NSJSONSerialization. El problema está causado por los caracteres Unicode escapados (freie_pl\u00e4tze en lugar de freie_plätze). Tiene dos opciones:

  1. Convierta el Unicode escapado a caracteres Unicode reales. Pruebe this SO answer
  2. Utilice otro motor JSON, como JSONKit. JSONKit también afirma ser más eficiente que NSJSONSerialization.
+0

¡Muchas gracias! Eso fue lo único que no alteré mientras examinaba las diferencias entre los datos que fallaban y los que funcionaban ...Sorprendentemente, los caracteres escapados solo parecen ser un problema para las teclas del diccionario, no para los valores ... –

+0

Por cierto, solo estoy viendo esto si uso 'NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves' opciones. ¿Es esta tu experiencia también? – Rob

+0

Hola de los comentarios del código 'AFNetworking'. :) ¡Gracias, realmente ayuda! – skywinder

4

Sé que esta pregunta ha sido respondida, pero creo que algunos principiantes pueden tener el mismo problema que yo y ser llevado a esta pregunta.

El mensaje EXC_BAD_ACCESS fue causado por JSON malformado. Como había usado accidentalmente el mismo nombre para un Objeto que causa problemas al convertir el JSON en un diccionario.

Annoyingly no apareció un error de formateo. Aquí está un ejemplo de la JSON que causó el problema:

"levels" : { 
    "level1": { 
     .... 
    }, 
    "level1": { 
     ... << All objects should have different names. This should be called level2. 
    }, 
    "level3": { 
     ... 
    } 

para solucionar el problema que tenía que asegurarse de que todos los objetos del mismo nivel tenían diferentes nombres.

1

Acaba de probar NSJSONSerialización hoy. Con iOS 7.1. Está funcionando. No se encontró ningún problema. Parece que Apple solucionó el problema.

NSString* jsonString = @"{ \"freie_pl\\u00e4tze\":null}"; 

NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 

NSError *error = nil; 
NSDictionary* jsonSerializationResult = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error]; 

NSLog(@"%@", jsonSerializationResult);