objectForKey stringValueでアプリがクラッシュしますか?
-
22-07-2019 - |
質問
配列内のオブジェクトをセットアップするために使用するクラスがあります。このクラスには、カスタム" initWithDictionary"があり、 JSON
辞書を解析します。ただし、 NSNull
を実行すると、アプリがクラッシュします。これを回避するために、例外を処理するクラスを設定します。そのため、文字列が NSNull
の場合、文字列は @""
に置き換えられます。または整数の場合は-1。
これは私のNullExtensionsクラスです:
@interface NSNull (valueExtensions)
-(int)intValue;
-(NSString *)stringValue;
@end
@implementation NSNull (valueExtensions)
-(int)intValue {
return -1;
}
-(NSString*)stringValue {
return @"";
}
@end
ただし、私のinitWithDictionaryメソッドでは、次のコードがアプリをクラッシュさせます:
self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];
解析されたディクショナリ内のオブジェクトが NSNull
であるか、有効な文字列を含んでいるかにかかわらず、機能しません。以下を実行する場合のみ(そして文字列がnullではない場合):
self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
この場合、 stringValue
は間違っていますか?もしそうなら、適切な NSNull
置換をセットアップするためにどのように適切に使用しますか?
Thx
解決
NSNull
にカテゴリを作成する代わりに、同様のカテゴリを NSString
に追加する必要があります(そのため、実際の文字列は応答しないためクラッシュします) stringValue)-代わりに、 NSDictionary
に" stringForKey
"のようなヘルパーカテゴリを作成してみてください。 Johanが投稿したコードを使用して NSString
を返します。おそらく、他のすべての型も空の文字列にマップされるようにする必要があります。
他のヒント
このような一般的なメソッドを追加するカテゴリをNSNullに本当に追加したくはありません本当に。これにより、アプリケーションの all インスタンスのNSNullの動作が変更されます。これには、プライベートな使用のみを目的として、基盤となるフレームワークによって作成されたものも含まれます。
「値が存在しない」という概念を表す値クラスが必要なため、代わりにこれらのデフォルト値を返す場合」、それを正確に表すクラスまたはインスタンスを作成します。
クラッシュする理由については、クラッシュの実際の詳細を見ずに伝えることはできませんでした。
そして、はい、そのような一般的なメソッドを追加するクラスにカテゴリを追加することは本当に それです。必要なのは、プラグインまたはフレームワーク内の1ビットのコードだけです:
if ([fooMaybeNull respondsToSelector: @selector(intValue)] bar = [fooMaybeNull intValue];
それほど大げさではありません-この種の意地の悪いカテゴリの追加により、正確に、厄介なクラッシュや誤動作をデバッグする必要がありました。
カテゴリを介してクラスにメソッドを追加する場合は、既存の機能から分離するためにメソッド名をプレフィックスします。まだ壊れやすいですが、扱いやすいほどです。
あなたが書いたNSNull拡張機能は私には問題ないように見えますが、NSNumberなどの他のクラスがこれを使用しているため、stringValueなどのメソッドを使用すると混乱する場合があります。
個人的には、この場合のNSNull置換は不要だと思います。簡単なテストを行ったばかりであれば、必要な場所でNSNullを交換できます。例:
id testObject = [parsedDictionary objectForKey:@"book_title"];
self.bookTitle = testObject==[NSNull null] ? @"" : testObject;
stringValue
の NSString
を要求しています。文字列を文字列に変換する必要はありません。
これを試してください:
if (![[parsedDictionary objectForKey:@"book_title"] isKindOfClass:[NSNull class]]) {
self.bookTitle = [parsedDictionary objectForKey:@"book_title"];
} else {
self.bookTitle = @"";
}
編集:作成した NSNull
のカテゴリは使用しないでください。あなたはそれを必要とせず、あなたもそれを望むべきではない。辞書のソースが NSNull
インスタンスを挿入する場合、先に進み、上記のコードを使用します。通常、キーに値が挿入されていないことが単純に予想されますが、その時点で [parsedDictionary objectForKey:@" book_title"]
が何かを返すかどうかを簡単に確認できます。
辞書が [NSNull null]
を返していることを確認しますか?デフォルトでは、キーの値が見つからない場合、辞書は [NSNull null]
ではなく nil
を返します。
ただし、私のinitWithDictionaryメソッドでは、次のコードがアプリをクラッシュさせます:
self.bookTitle = [[parsedDictionary objectForKey:@"book_title"] stringValue];
解析されたディクショナリのオブジェクトがNSNullであるか、有効な文字列を含んでいるかどうかにかかわらず、機能しません。
stringValue
は NSString
の有効なメソッドではないため、これは理にかなっています。 NSValue
とそのサブクラスで機能しますが、 NSString
では機能しません。