有時(shí)候服務(wù)器很煩不靠譜陵刹,老是不經(jīng)意間返回null,所以在iOS端不得不校驗(yàn)它的類型等欢嘿。譬如:返回的數(shù)組為null,首先得判斷類型是不是NSArray 還得判斷非空衰琐。
NSArray *products = data[@"省心寶"];
if ([products isKindOfClass:[NSArray class]] && products.count > 0)
{
// TO DO
}
這種問(wèn)題一多,就會(huì)影響我們程序猿的心情际插,并且代碼也變得冗余了碘耳,所以換種技巧solve it。
思路:重寫NSNull的消息轉(zhuǎn)發(fā)方法, 讓他能處理這些異常的方法框弛。
常見(jiàn)的幾種類型為"",0,{},[]了辛辨。
所以,創(chuàng)建一個(gè)NSNull的分類 NSNull (InternalNullExtention)
具體實(shí)現(xiàn)如下:
.h文件
#import <Foundation/Foundation.h>
@interface NSNull (InternalNullExtention)
@end
.m文件
#import "NSNull+InternalNullExtention.h"
#define NSNullObjects @[@"",@0,@{},@[]]
@implementation NSNull (InternalNullExtention)
+ (void)load
{
@autoreleasepool {
[self wt_swizzleInstanceMethodWithClass:[NSNull class] originalSel:@selector(methodSignatureForSelector:) replacementSel:@selector(wt_methodSignatureForSelector:)];
[self wt_swizzleInstanceMethodWithClass:[NSNull class] originalSel:@selector(forwardInvocation:) replacementSel:@selector(wt_forwardInvocation:)];
}
}
- (NSMethodSignature *)wt_methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (!signature) {
for (NSObject *object in NSNullObjects) {
signature = [object methodSignatureForSelector:aSelector];
if (!signature) {
continue;
}
if (strcmp(signature.methodReturnType, "@") == 0) {
signature = [[NSNull null] methodSignatureForSelector:@selector(wt_nil)];
}
return signature;
}
return [self wt_methodSignatureForSelector:aSelector];
}
return signature;
}
- (void)wt_forwardInvocation:(NSInvocation *)anInvocation
{
if (strcmp(anInvocation.methodSignature.methodReturnType, "@") == 0)
{
anInvocation.selector = @selector(wt_nil);
[anInvocation invokeWithTarget:self];
return;
}
for (NSObject *object in NSNullObjects)
{
if ([object respondsToSelector:anInvocation.selector])
{
[anInvocation invokeWithTarget:object];
return;
}
}
[self wt_forwardInvocation:anInvocation];
// [self doesNotRecognizeSelector:aSelector];
}
- (id)wt_nil
{
return nil;
}
+ (void)wt_swizzleInstanceMethodWithClass:(Class)clazz originalSel:(SEL)original replacementSel:(SEL)replacement
{
Method originMethod = class_getInstanceMethod(clazz, original);
Method replaceMethod = class_getInstanceMethod(clazz, replacement);
if (class_addMethod(clazz, original, method_getImplementation(replaceMethod), method_getTypeEncoding(replaceMethod))
{
class_replaceMethod(clazz, replacement, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));
}
else
{
method_exchangeImplementations(originMethod, replaceMethod);
}
}
@end
測(cè)試代碼就不加了。