2012-02-08 7 views
20

Ce qui suit est dans mon fichier .h:Initializing NSDictionary

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

C'est le fichier .m pour initialiser le 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]; 
} 

Le problème est seulement les quatre premiers objets et les clés sont ajoutées. Après cela, ils ne sont pas ajoutés au dictionnaire commençant par place.name, @ "name". J'ai fait un NSLog sur le dictionnaire entier et les seules choses sorties étaient les quatre premières valeurs comme je l'ai mentionné alors j'ai fait un NSLog sur place.name et il sort une valeur donc je sais que quelque chose devrait aussi être sorti pour cette clé/valeur paire. Y a-t-il quelque chose qui me manque ici? Je suis curieux de savoir pourquoi toutes les valeurs ne sont pas initialement ajoutées au NSDictionary?

Répondre

43

La raison pour laquelle ils ne sont pas ajoutés est parce qu'un objet est nul qui marque la fin du dictionnaire. Vous devez être sûr que chaque objet n'est pas nil et si c'est le cas, vous pouvez utiliser [NSNull null] à la place. Utilisez également self.originalValues = ... pour gérer correctement la mémoire. Assurez-vous que tout ce qui utilise le dictionnaire vérifie/peut gérer les valeurs NSNull.

Exemple d'utilisation 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 J'évite cette expression ternaire dans tous mes codages C et C++. Mais puisque c'est l'objectif-c qui est généralement compilé en utilisant gcc ou llvm d'Apple, je ne trouve aucun problème à l'utiliser. – Joe

54

Si l'un des objets est nil, vous pouvez attraper beaucoup plus rapidement si vous utilisez la nouvelle syntaxe littérale pour l'initialisation d'un NSDictionary (ci-dessous). Cette syntaxe est non seulement plus courte, mais aussi plus robuste: vous obtiendrez une erreur d'exécution si l'un de vos objets est nil, au lieu de poursuivre silencieusement l'exécution avec les données incomplètes.

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

Alors que la syntaxe littérale est beaucoup plus agréable et préférée, je ne suis pas sûr que l'OP recherche une erreur d'exécution quand une valeur est 'nil'. – Joe

0

Pour éviter nil accidentelle dans un dictionnaire la meilleure solution serait si vous combinez les deux techniques utilisant le littéral et l'opérateur ternaire comme

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

Note:

(anyValueOrVariable?: @ "anyOtherValueOrVariable")

est une abréviation et signifie le même que

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