美文网首页
NSNull 的 Crash问题解决

NSNull 的 Crash问题解决

作者: 5c3c832f76b0 | 来源:发表于2018-07-12 11:36 被阅读0次

    解决NSNull造成的crash问题

    在我们的开发中,很多时候后台会返回null,到了我们iOS这一端,就成为了NSNull 对象,就会发生很多的crash现象.

    只要解决此问题,需要将创建一个NSNull全局分类,然后加入以下代码即可

    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            @autoreleasepool {
                [self tf_replaceWithOriginalMethod:@selector(length) replaceSelector:@selector(tf_length)];
                [self tf_replaceWithOriginalMethod:@selector(integerValue) replaceSelector:@selector(tf_integerValue)];
                [self tf_replaceWithOriginalMethod:@selector(objectForKey:) replaceSelector:@selector(tf_objectForKey:)];
                [self tf_replaceWithOriginalMethod:@selector(objectAtIndex:) replaceSelector:@selector(tf_objectAtIndex:)];
            }
        });
    }
    
    + (void)tf_replaceWithOriginalMethod:(SEL)originalSelector replaceSelector:(SEL)replaceSelector {
        Class class = [self class];
        //原来的方法
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        //替换的新方法
        Method replaceMethod = class_getInstanceMethod(class, replaceSelector);
        //先尝试給源SEL添加IMP,这里是为了避免源SEL没有实现IMP的情况
        BOOL didAddMethod = class_addMethod(class,originalSelector,
                                            method_getImplementation(replaceMethod),
                                            method_getTypeEncoding(replaceMethod));
        if (didAddMethod) {//添加成功:说明源SEL没有实现IMP,将源SEL的IMP替换到交换SEL的IMP
            class_replaceMethod(class,replaceSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {//添加失败:说明源SEL已经有IMP,直接将两个SEL的IMP交换即可
            method_exchangeImplementations(originalMethod, replaceMethod);
        }
    }
    
    - (NSInteger)tf_length {
        NSAssert(NO, @"null..");
        return 0;
    }
    
    - (NSInteger)tf_integerValue {
        NSAssert(NO, @"null..");
        return 0;
    }
    
    - (id)tf_objectForKey:(id)key{
        NSAssert(NO, @"null..");
        return nil;
    }
    
    - (id)tf_objectAtIndex:(NSInteger)index{
        NSAssert(NO, @"null..");
        return nil;
    }
    
    

    注:由于下面的方法中,为了方便项目的调试,使用了断言.调试cocoa程序在程序出错时,不会马上停止。使用宏NSAssert可以让程序出错时马上抛出异常。在debug情况下,所有NSAssert都会被执行。在release下不希望NSAssert被执行,我们通常在release种将断言设置成禁用。

    设置方法:在Build Settings菜单,找到Preprocessor Macros项,Preprocessor Macros项下面有一个选择,用于程序生成配置:Debug版和Release版。选择 Release项,设置NS_BLOCK_ASSERTIONS,不进行断言检查。

    相关文章

      网友评论

          本文标题:NSNull 的 Crash问题解决

          本文链接:https://www.haomeiwen.com/subject/xeblpftx.html