2012-02-08 19 views
20

La siguiente es en mi archivo .h:Inicializando NSDictionary

NSDictionary *originalValues; 
    @property (nonatomic, retain) NSDictionary *originalValues; 

Este es el archivo .m para inicializar el NSDictionary.

@synthesize originalValues; 

- (void)viewDidLoad { 

// copy original values when view loaded 
originalValues = [[NSDictionary alloc] initWithObjectsAndKeys:place.city, @"city", place.cuisine, @"cuisine", 
       place.latitude, @"latitude", place.longitude, @"longitude", place.name, @"name", place.rating, 
       @"rating", place.state, @"state", place.street, @"street", place.telephone, @"telephone", 
       place.timesVisited, @"times visited", place.uppercaseFirstLetterOfName, @"first letter", 
       place.website, @"website", place.zipcode, @"zipcode", nil]; 
} 

El problema es que solo se están agregando los primeros cuatro objetos y claves. Después de eso, no se están agregando al diccionario comenzando con place.name, @ "name". Hice un NSLog en todo el diccionario y los únicos resultados fueron los primeros cuatro valores, como lo mencioné, así que II realizó un NSLog en place.name y está generando un valor, por lo que sé que también se debe generar algo para esta clave/valor par. ¿Hay algo que me falta aquí? Tengo curiosidad por saber por qué todos los valores no se están agregando inicialmente al NSDictionary.

Respuesta

43

La razón por la que no se agregan es porque un objeto es nulo y marca el final del diccionario. Debe asegurarse de que cada objeto no sea nil y, si lo es, puede usar [NSNull null] en lugar de este. También use self.originalValues = ... para una gestión de memoria adecuada. Solo asegúrese de que lo que utiliza el diccionario verifique/pueda manejar los valores NSNull.

Ejemplo usando gnu ternary extension:

self.originalValues = [[NSDictionary alloc] initWithObjectsAndKeys: 
         place.city ?: [NSNull null], @"city", 
         place.cuisine ?: [NSNull null], @"cuisine", 
         place.latitude ?: [NSNull null], @"latitude", 
         place.longitude ?: [NSNull null], @"longitude", 
         place.name ?: [NSNull null], @"name", 
         place.rating ?: [NSNull null], @"rating", 
         place.state ?: [NSNull null], @"state", 
         place.street ?: [NSNull null], @"street", 
         place.telephone ?: [NSNull null], @"telephone", 
         place.timesVisited ?: [NSNull null], @"times visited", 
         place.uppercaseFirstLetterOfName ?: [NSNull null], @"first letter", 
         place.website ?: [NSNull null], @"website", 
         place.zipcode ?: [NSNull null], @"zipcode", 
         nil]; 
+2

@TReddy evito que la expresión ternaria en toda mi C y C++ codificación. Pero como esto es objetivo-c, que generalmente solo se compila con gcc o con Apple's llvm, no encuentro problemas con su uso. – Joe

54

Si uno de los objetos es nil, se puede tomar mucho más rápido que si se utiliza la nueva sintaxis literal para inicializar un NSDictionary (abajo). Esta sintaxis no solo es más corta, sino también más robusta: en realidad obtendrá un error de tiempo de ejecución si uno de sus objetos es nil, en lugar de continuar la ejecución en silencio con los datos incompletos.

originalValues = @{ @"city"  : place.city, 
        @"latitude" : place.latitude, 
        // etc. 
        }; 
+0

Si bien la sintaxis literal es mucho más agradable y preferida, no estoy seguro de que OP esté buscando un error de tiempo de ejecución cuando un valor es 'nil'. – Joe

0

Para evitar nula accidental en cualquier diccionario la mejor solución sería que si se combinan las dos técnicas utilizando el literal y el operador ternario como

self.originalValues = @{ @"city" : (place.city ?: @"city"), 
         @"latitude" : (place.latitude ?: [NSNull null]), 
         // etc. 
         }; 

Nota:

(anyValueOrVariable?: @ "anyOtherValueOrVariable")

es una abreviatura y significa lo mismo que

(anyValueOrVariable! = 0)? anyValueOrVariable: @ "anyOtherValueOrVariable"