2012-02-08 17 views
20

Il seguente è nel mio file h:inizializzazione NSDictionary

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

Questo è il file .m a init il 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]; 
} 

Il problema sono solo i primi quattro oggetti e le chiavi vengono aggiunte. Dopodiché, non vengono aggiunti al dizionario a partire da place.name, @ "name". Ho fatto un NSLog sull'intero dizionario e le uniche cose emesse erano i primi quattro valori come ho accennato, quindi ho fatto un NSLog su place.name e sta emettendo un valore quindi so che qualcosa dovrebbe essere emesso anche per questa chiave/valore paio. C'è qualcosa che mi manca qui? Sono curioso di sapere perché tutti i valori non vengono inizialmente aggiunti al NSDictionary?

risposta

43

Il motivo per cui non vengono aggiunti è perché un oggetto è nullo che segna la fine del dizionario. Devi essere sicuro che ogni oggetto non sia nil e se lo è puoi usare [NSNull null] al posto di esso. Utilizzare anche self.originalValues = ... per una corretta gestione della memoria. Assicurati solo che cosa usi mai il dizionario controlla/può gestire i valori NSNull.

Esempio con 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 che l'espressione ternaria in tutta la mia C e C++ di codifica. Ma dal momento che questo è oggettivo-c che è generalmente compilato solo usando gcc o Apple llvm, non trovo alcun problema con l'utilizzo. – Joe

54

Se uno degli oggetti è nil, si può prendere molto più veloce se si utilizza la nuova sintassi letterale per inizializzare un NSDictionary (qui di seguito). Questa sintassi non è solo più breve, ma anche più robusta: si otterrà effettivamente un errore di runtime se uno dei tuoi oggetti è nil, invece di continuare silenziosamente l'esecuzione con i dati incompleti.

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

Mentre la sintassi letterale è molto più bella e preferita, non sono sicuro che l'OP cerchi un errore di runtime quando un valore è 'nil'. – Joe

0

Per evitare nullo accidentale in alcun dizionario la soluzione migliore sarebbe se si combinano le due tecniche che utilizzano il letterale e l'operatore ternario come

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

Nota:

(anyValueOrVariable?: @ "anyOtherValueOrVariable")

è una abbreviazione e significa uguale a

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