Jsonにおけるnullの処理方法

2551 ワード

問題記述サーバがjsonデータを返す場合、次のようなデータが頻繁に発生します.
"somevalue":null
JsonKitというサードパーティライブラリで解析したデータはsomevalue="""";このデータ型はnilでもStringでもないNSNullのオブジェクトです.このオブジェクトに直接メッセージを送信すると、直接クラッシュします.エラー:
-[NSNulllength]: unrecognized selector sent to instance 0x388a4a70
解決方法1、最初の解決方法は、現在遭遇しているクラッシュに対処するために、どのフィールドが空である可能性があるかを見て、そのフィールドの使用前に判断を行い、クラッシュ時のエラーメッセージから、このようなフィールドが解析されたオブジェクトはNSNullタイプであることがわかるので、このタイプであるかどうかを直接判断することができる.
if(![isKindOfClass:[NSNullclass]]){xxxxxxx;}
ただし、各フィールドごとにこの操作を行うことはできないため、この方法は特定のフィールドを判断するのにのみ適用されます.2、nullを文字列で一致させて置き換えます.サーバから返されたJsonを取得すると、結果が返されるとstringオブジェクトが返され、nullを空の文字に置き換えます」と解析します.
json = [jsonStr stringByReplacingOccurrencesOfString:@":null"withString:@":"""];
この方法はNSStringのcategoryと書くことができ,対応する方法を呼び出せば比較的簡潔であるが,string,array,dictionaryを判断するには,少なからぬ作業量である.また、サーバのデータフォーマットも保証されず、一致しない可能性があります.3、最后に仕方がなくて、解析の时に手をつけるしかなくて、NSNullタイプの値をnilに交换します.一般的にtoolメソッドを書き、解析時に呼び出します.しかし、面倒なのでマクロを書こうとしたが、驚くべき検索でマクロに戻り値があることが分かった.結果は以下のようになった.
#define VerifyValue(value)
({idtmp;
      if([value isKindOfClass:[NSNullclass]])
            tmp =nil;
      else
            tmp = value;
      tmp;
})

マクロの最後の文は戻り値です.次に、データの解析時にマクロを呼び出します.
contact.contactPhone = VerifyValue(contactDic[@"send_ContactPhone"]);
この方法は実は方法と似たような考えだ.4、もしあなたがAFNetworkというライブラリを使ってネットの要求をするならば、以下のコードでこの嫌な空の値を取り除くことができます
((AFJSONResponseSerializer*)manager.responseSerializer).removesKeysWithNullValues=YES;
以上のように設定すると、NSNullの値はすべてnilになります.5、Null Safe githhubにはNull SafeというCategoryがあり、実行時に操作し、空の値をnilにすることができますが、nilは安全で、nilオブジェクトに潰さずにメッセージを送信することができます.このcategoryはNullSafeを使えばとても便利です.mをプロジェクトに追加すればいいので、他の操作をする必要はなく、NullSafeは実行時に自動的にロードされます.詳細はGithubで確認してください:NullSafeここにはもう一つの極めて簡単なパッケージ方法があります.
#import"NSNull+OVNatural.h"
@implementationNSNull(OVNatural)
- (void)forwardInvocation:(NSInvocation *)invocation
{
if([selfrespondsToSelector:[invocation selector]]) {
[invocation invokeWithTarget:self];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *sig = [[NSNull class] instanceMethodSignatureForSelector:selector];
if(sig ==nil) {
sig = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
returnsig;
}
@end

[NSMethodSignature signatureWithObjCTypes:"@^vc"]の機能については、次の2つの記事Objective-C Runtime Programming Guide Type Encodingsを参照してください.
文中国側の法源はネット上で見た多種の方法の整理から、一定の自分の理解を加えた.もしオリジナル者が見たら教えてください.私は元博の住所を追加したり削除したりします.