iOS 奇技yin巧--解決伺服器返回NSNull問題,iosnsnull
iOS 奇技yin巧–解決伺服器返回NSNull問題
奇技yin巧 指過於奇巧而無益的技藝與製品.
轉載請註明出處 http://blog.csdn.net/uxyheaven/article/details/48299599
系列文章請看http://blog.csdn.net/uxyheaven/article/category/5800569
問題描述
眾所周知,伺服器返回的資料時不時的就不靠譜一下
{ "名字":"漂亮妹子", "備胎們":, "年紀":18}
明明木有備胎, 結果返回@[]也好啊, 偏偏返回一個null.
這個時候呢, 我們native端就得在取倒資料的時候, 先判斷類型是不是NSArray 還得判斷非空
NSArray *boys = data[@"備胎們"]; if ([boys isKindOfClass:[NSArray class]] && boys.count > 0) { doSomething }
校正的代碼寫多了總是很影響心情, 伺服器就不能加個空的就不返回或者返回@[]麼, 就不能讓我們安心的寫個備胎1號 = boys[0]麼?
解
讓我們來看看奇技的解決辦法吧.
思路:重寫NSNull的訊息轉寄方法, 讓他能處理這些異常的方法.
訊息轉寄的相關知識不瞭解的同學需要自行搜尋下. 在寫的時候,我們要考慮 @"",@0,@{},@[]這幾種常用的類型空值, 再問到NSNull的一些不屬於它的方法的時候, 如果那些空值可以響應的時候就丟給他們去處理去.
// count理所當然的就等於0了int count = boys.count;
奇技有了, 接著是yin巧.
如果我們要二號備胎囧麼辦?
id boy = boys[1];
這可就直接越界了啊. 我們仔細的看下NSArray裡的方法, 是不是發現一個規律, 基本上返回的是id類型的是取裡面的元素的. 既然這樣, 那麼我們就乾脆只要你問NSArray裡要一個元素, 我就都返回’nil’給你.
if (strcmp(anInvocation.methodSignature.methodReturnType, "@") == 0){ anInvocation.selector = @selector(__uxy_nil); [anInvocation invokeWithTarget:self]; return;}- (id)__uxy_nil{ return nil;}
完整的代碼如下
// .h檔案@interface NSNull (XY_InternalNullExtention)@end// .m檔案#define UXY_NullObjects @[@"",@0,@{},@[]]@implementation NSNull (XY_InternalNullExtention)- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector{ NSMethodSignature *signature = [super methodSignatureForSelector:selector]; if (signature != nil) return signature; for (NSObject *object in UXY_NullObjects) { signature = [object methodSignatureForSelector:selector]; if (signature) { if (strcmp(signature.methodReturnType, "@") == 0) { signature = [[NSNull null] methodSignatureForSelector:@selector(__returnNil)]; } break; } } return signature;}- (void)forwardInvocation:(NSInvocation *)anInvocation{ if (strcmp(anInvocation.methodSignature.methodReturnType, "@") == 0) { anInvocation.selector = @selector(__uxy_nil); [anInvocation invokeWithTarget:self]; return; } for (NSObject *object in UXY_NullObjects) { if ([object respondsToSelector:anInvocation.selector]) { [anInvocation invokeWithTarget:object]; return; } } [self doesNotRecognizeSelector:anInvocation.selector];}- (id)__uxy_nil{ return nil;}@end
測試的代碼
UXY_EXPECTED( ((NSArray *)[NSNull null])[1] == nil ); UXY_EXPECTED( ((NSDictionary *)[NSNull null])[nil] == nil ); UXY_EXPECTED( [((NSString *)[NSNull null]) substringToIndex:2] == nil );
這個檔案在我的開源庫的NSNull+XY檔案裡, 若果本文對你有所啟發, 歡迎給個star.
https://github.com/uxyheaven/XYQuick
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。