web-dev-qa-db-fra.com

Initialisation de NSDictionary

Ce qui suit est dans mon fichier .h:

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

Il s'agit du fichier .m pour lancer 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 que seuls les quatre premiers objets et clés sont ajoutés. Après cela, ils ne sont pas ajoutés au dictionnaire commençant par place.name, @ "name". J'ai fait un NSLog sur tout le dictionnaire 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 génère une valeur, donc je sais que quelque chose devrait également ê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?

24
kschins

La raison pour laquelle ils ne sont pas ajoutés est parce qu'un objet est nul, ce qui marque la fin du dictionnaire. Vous devez vous assurer que chaque objet n'est pas nil et s'il l'est, vous pouvez utiliser [NSNull null] à sa place. Utiliser aussi self.originalValues = ... pour une bonne gestion de la mémoire. Assurez-vous simplement que ce qui utilise le dictionnaire vérifie/peut gérer les valeurs NSNull.

Exemple utilisant 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];
48
Joe

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

originalValues = @{ @"city"     : place.city, 
                    @"latitude" : place.latitude,
                    // etc.
                  };
62
Macondo2Seattle

Pour éviter le zéro accidentel dans un dictionnaire, la meilleure solution serait de combiner les deux techniques en utilisant l'opérateur littéral et l'opérateur ternaire comme

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

Remarque:

(anyValueOrVariable?: @ "anyOtherValueOrVariable")

est une abréviation et signifie la même chose que

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

5
BootMaker