+[NSDictionary dictionaryWithObjectsAndKeys:]でNSDictionaryを作成したい。私のキーの 1 つに文字列がありますが、文字列が. 文字列が の場合、リストが途中で終了するため、後で入力した他の値のキー ペアは無視されます。に値がある可能性に対処する標準的な方法は何ですか?nil
nil
nil
NSDictionary
4 に答える
文字列が null かどうかを確認する必要があります。[NSNull null]
そうである場合は、文字列の代わりに追加します。
NSDictionary オブジェクトの作成は、多くのオブジェクトがあり、それらが nil の場合はディクショナリに含めるべきではない場合、面倒な場合があります。
私にとって、NSNull は解決策であると同時に大きな問題でもあります。他のオブジェクトで使用するために NSDictionary オブジェクトを作成する場合、nil値を処理する方法は 2 つあります。NSNull オブジェクトを辞書に追加してから、値を読み取るときに NSNull 値を確認します。これにより、作成時点ではきれいなコードが作成されますが、値を読み取るときに面倒になります。元。ディクショナリ内のすべてのキーをチェックする必要がありますか、それとも nil ではないことが保証されているものがありますか? また、NSNull 値が除外されていない場合、オブジェクト メッセージを送信しようとすると例外が発生します。
2 番目の方法は、NSNull 値を辞書に追加しないことです。キーが設定されていない場合、 [ someDictionary objectForKey: someKey ] は単純に nil を返すため、これは NSDictionary を読み取るときに便利です。このアプローチにより、値を読み取るときは非常に簡単になりますが、実際には作成時に厄介なコードになることは間違いありません。元。NSMutableDictionary を作成し、値を追加する前に nil をチェックし、最後に不変のコピーを返しますか?
解決
私にとっての解決策は、2 つのカテゴリを作成することでした。これにより、本質的に、作成側と読み取り側の両方が簡単になります。
NSDictionary を作成するときは、次のように possible-nil 値をラップするだけです
[NSDictionary dictionaryWithObjectsAndKeysIngoringNull:
[NSNull nullWhenNil:val1], @"value1",
[NSNull nullWhenNil:val2], @"value2",
...
nil];
このコードは、アプローチ 1 とほぼ同じくらい単純ですが、値を読み取るときはかなり簡単になります。
カテゴリは次のとおりです (ARC 対応コードと非 ARC コードの両方で機能します)。
NSDictionary の追加:
@implementation NSDictionary (NullAddition)
+ (id)dictionaryWithObjectsAndKeysIngnoringNull:(id)firstObject, ... {
NSMutableArray* objects = [NSMutableArray array];
NSMutableArray* keys = [NSMutableArray array];
va_list args;
va_start(args, firstObject);
for (id object = firstObject; object; object = va_arg(args, id)) {
id key = va_arg(args, id);
if (!key)
break;
if (![object isKindOfClass:[NSNull class]]) {
[objects addObject:object];
[keys addObject:key];
}
}
va_end(args);
return [self dictionaryWithObjects:objects forKeys:keys];
}
@end
NSNull追加
@implementation NSNull (NullAddition)
+ (id)nullWhenNil:(id)obj {
return (obj ? obj : [self null]);
}
@end
幸運を!
にデータ (キーまたは値) を挿入しようとするとNSDictionary
、実行時エラーが発生します。したがって、ディクショナリで null データを処理する必要はありません。
'-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Test)'
と
'-[__NSCFDictionary setObject:forKey:]: attempt to insert nil key'
ただし、これは、クラッシュを防ぐためにデータをディクショナリに入れる前に、データの有効性をチェックする責任があることを意味します。