眾所周知,服務(wù)器返回的數(shù)據(jù)時(shí)不時(shí)的就不靠譜一下,返回NSNull類型引起客戶端crash,這種定時(shí)炸彈我們?nèi)绻ㄟ^(guò):
[des isKindOfClass:[NSNull class]]
這樣判斷只能解決某個(gè)問(wèn)題炮沐,然而對(duì)于不確定的返回null無(wú)法下手徽惋,另外到處寫這種代碼看起來(lái)也是很不爽赘理。
解決:利用消息轉(zhuǎn)發(fā)
消息轉(zhuǎn)發(fā)不了解的可以自行百度
在寫的時(shí)候,我們要考慮@"",@0,@{},@[]這幾種常用的類型空值, NSNull實(shí)例在調(diào)用到一些不屬于它的方法的時(shí)候, 如果@"",@0,@{},@[]可以響應(yīng)的時(shí)候就丟給他們?nèi)ヌ幚砣ァ?/p>
比如 調(diào)用 intvalue,可以丟給@0去處理公壤。
詳細(xì)代碼說(shuō)明
#import "NSNull+safe.h"
#define NullObjects @[@"",@0,@{},@[]]
@implementation NSNull (safe)
//必須返回一個(gè)方法簽名不能為空
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
NSMethodSignature *signature = [super methodSignatureForSelector:selector];
if (signature != nil) return signature;
for (NSObject *object in NullObjects) {
signature = [object methodSignatureForSelector:selector];
if (signature) {
//strcmp比較兩個(gè)字符串换可,相同返回0
//這里 @ 是指返回值為對(duì)象 id
if (strcmp(signature.methodReturnType, "@") == 0) {
signature = [[NSNull null] methodSignatureForSelector:@selector(__returnNil)];
}
break;
}
}
return signature;
}
//消息轉(zhuǎn)發(fā)的最后一步
- (void)forwardInvocation:(NSInvocation *)anInvocation {
//如果返回值是對(duì)象 設(shè)置方法為_(kāi)_returnNil
if (strcmp(anInvocation.methodSignature.methodReturnType, "@") == 0) {
anInvocation.selector = @selector(__returnNil);
[anInvocation invokeWithTarget:self];
return;
}
//遍歷 查看 @"",@0,@{},@[] 那個(gè)響應(yīng)了selector,然后丟給它去執(zhí)行
for (NSObject *object in NullObjects) {
if ([object respondsToSelector:anInvocation.selector]) {
[anInvocation invokeWithTarget:object];
return;
}
}
//拋出異常
[self doesNotRecognizeSelector:anInvocation.selector];
}
- (id)__returnNil {
return nil;
}
@end
demo地址
歡迎star