iOS开发中<null>的处理

在iOS开发过程中经常需要与服务器进行数据通讯,JSON就是一种常用的高效简洁的数据格式。

问题:

在项目中,一直遇到一个坑的问题,程序在获取某些数据之后莫名崩溃。原因是:由于服务器的数据库中有些字段为空,然后以JSON形式返回给客户端时就会出现这样的数据:repairs = “”

这个数据类型不是nil 也不是 String。 解析成对象之后,如果直接向这个对象发送消息(eg:length,count 等等)就会直接崩溃。提示错误为:

-[NSNull length]: unrecognized selector sent to instance

解决方案:

用了一个Category,叫做NullSafe 。

NullSafe思路:在运行时操作,把这个讨厌的空值置为nil,而nil是安全的,可以向nil对象发送任何message而不会奔溃。这个category使用起来非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,很简单。

NullSafe 源码:

#import "NSNull+NullSafe.h"
#import <objc/runtime.h>
#ifndef NULLSAFE_ENABLED
#define NULLSAFE_ENABLED 1
#endif
@implementation NSNull (NullSafe)
#if NULLSAFE_ENABLED
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector{
    @synchronized([self class]){
        //look up method signature
        NSMethodSignature *signature = [super methodSignatureForSelector:selector];
        if (!signature){
            //not supported by NSNull, search other classes
            static NSMutableSet *classList = nil;
            static NSMutableDictionary *signatureCache = nil;
            if (signatureCache == nil){
                classList = [[NSMutableSet alloc] init];
                signatureCache = [[NSMutableDictionary alloc] init];
                //get class list
                int numClasses = objc_getClassList(NULL, 0);
                Class *classes = (Class *)malloc(sizeof(Class) * (unsigned long)numClasses);
                numClasses = objc_getClassList(classes, numClasses);
                //add to list for checking
                NSMutableSet *excluded = [NSMutableSet set];
                for (int i = 0; i < numClasses; i++){
                    //determine if class has a superclass
                    Class someClass = classes[i];
                    Class superclass = class_getSuperclass(someClass);
                    while (superclass){
                        if (superclass == [NSObject class]){
                            [classList addObject:someClass];
                            break;
                        }
                        [excluded addObject:NSStringFromClass(superclass)];
                        superclass = class_getSuperclass(superclass);
                    }
                }
                //remove all classes that have subclasses
                for (Class someClass in excluded){
                    [classList removeObject:someClass];
                }
                //free class list
                free(classes);
            }
            //check implementation cache first
            NSString *selectorString = NSStringFromSelector(selector);
            signature = signatureCache[selectorString];
            if (!signature){
                //find implementation
                for (Class someClass in classList){
                    if ([someClass instancesRespondToSelector:selector]){
                        signature = [someClass instanceMethodSignatureForSelector:selector];
                        break;
                    }
                }
                //cache for next time
                signatureCache[selectorString] = signature ?: [NSNull null];
            }else if ([signature isKindOfClass:[NSNull class]]){
                signature = nil;
            }
        }
        return signature;
    }
}
- (void)forwardInvocation:(NSInvocation *)invocation{
    invocation.target = nil;
    [invocation invoke];
}
#endif
@end

详细的请去Github上查看,点击阅读原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoxiaobukuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值