web-dev-qa-db-ja.com

NSDictionaryの初期化

以下は私の.hファイルにあります:

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

これは、NSDictionaryを初期化する.mファイルです。

@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];
}

問題は、最初の4つのオブジェクトとキーのみが追加されることです。その後、place.name、@ "name"で始まる辞書に追加されません。私は辞書全体でNSLogを行いましたが、出力されたのは私が言及したように最初の4つの値だったので、IIはplace.nameでNSLogを行い、値を出力していますペア。ここに足りないものはありますか?すべての値が最初にNSDictionaryに追加されないのはなぜですか?

24
kschins

それらが追加されない理由は、オブジェクトが辞書の終わりを示すnilであるためです。各オブジェクトがnilではないことを確認する必要があります。そうでない場合は、代わりに[NSNull null]を使用できます。適切なメモリ管理のためにself.originalValues = ...も使用します。辞書チェックを使用するものがNSNull値を処理できることを確認してください。

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

オブジェクトの1つがnilである場合、NSDictionaryの初期化に新しいリテラル構文を使用すると(以下を参照)、はるかに速くキャッチできます。この構文は短いだけでなく、より堅牢です。オブジェクトの1つがnilである場合、不完全なデータで実行をサイレントに継続する代わりに、実際にランタイムエラーが発生します。

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

辞書での偶発的なnilを回避するための最良の解決策は、次のようなリテラルと三項演算子を使用して2つのテクニックを組み合わせる場合です。

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

注:

(anyValueOrVariable?:@ "anyOtherValueOrVariable")

略語であり、同じ意味

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

5
BootMaker