• iOS 增强程序健壮性


      在项目开发中,和服务端交互数据时,若服务端数据为空时,会出现 <null>,客户端解析时会 Crash,为了增强程序的健壮性,减少 Crash 的发生,可以使用 NullSafe 这个类别。它对不识别的类型返回 nil,而不是抛出异常,它减少了例如因为 JSON 解析中 数组或字符串为 null 时导致的 Crash。这些异常对客户端来说是不可预期的。

      使用时只需要把 NullSafe.m 文件拖进工程就可以了,它在程序运行时自动加载,你不需要再导入其他头文件了。

      如果想要禁止 NullSafe 的话,需要设置:NULLSAFE_ENABLED=0,或者在 .pch 文件中添加:

    #ifdef DEBUG
    #define NULLSAFE_ENABLED 0
    #endif

      附:NullSafe 源码:

    #import <objc/runtime.h>
    #import <Foundation/Foundation.h>
    
    
    #ifndef NULLSAFE_ENABLED
    #define NULLSAFE_ENABLED 1
    #endif
    
    
    #pragma GCC diagnostic ignored "-Wgnu-conditional-omitted-operand"
    
    
    @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

      

  • 相关阅读:
    艾伟_转载:学习 ASP.NET MVC (第三回)实战篇 狼人:
    艾伟_转载:40条ASP.NET开发Tip 狼人:
    艾伟_转载:20条.NET编码习惯 狼人:
    艾伟_转载:数组排序方法的性能比较(上):注意事项及试验 狼人:
    艾伟_转载:使用LINQ to SQL更新数据库(上):问题重重 狼人:
    艾伟_转载:学习 ASP.NET MVC (第四回)实战篇 狼人:
    艾伟_转载:学习 ASP.NET MVC (第五回)理论篇 狼人:
    艾伟_转载:ASP.NET MVC 2博客系列 狼人:
    艾伟_转载:Cookie是什么?用法是怎样?与SESSION有什么区别?(二) 狼人:
    艾伟_转载:ASP.NET MVC 2博客系列之一:强类型HTML辅助方法 狼人:
  • 原文地址:https://www.cnblogs.com/ZachRobin/p/7245582.html
Copyright © 2020-2023  润新知