NSNull 的 Crash问题解决

解决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,不进行断言检查。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容