美文网首页
iOS 感受黑魔法Method Swizzling的魅力(二)

iOS 感受黑魔法Method Swizzling的魅力(二)

作者: Hem1ngTai | 来源:发表于2019-08-08 10:26 被阅读0次

    上一篇介绍了Method Swizzling的相关方法,也介绍了一些常用场景,今天就详细介绍一下如何使用Method Swizzling来拦截系统常见崩溃,感受Method Swizzling带来的真正魅力。

    要拦截系统常见的崩溃,诸如数组越界,截取子串,插入空值等,就要先交换系统的方法,再去拦截系统抛出的异常信息,举个🌰,现在要截取数组越界的崩溃,看代码:

    NSArray *array = @[@"1",@"2",@"3"];
    NSLog(@"%@", array[3]);
    

    正常情况下,这段代码是肯定会崩溃的,看控制台输出的崩溃信息:

    *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]'
    

    现在我们要拦截这个崩溃,首先在调用objectAtIndexdSubscript方法之前(我们调用array[3]本质上就是调用objectAtIndexdSubscript),我们要先交换这个方法,看代码:

    + (void)ht_interceptArrayCrashCausedByIndexBeyondBounds {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
        Class clsI = NSClassFromString(@"__NSArrayI");
        [HTCrashReporter ht_swizzleInstanceMethodForClass:clsI
                                         originalSelector:@selector(objectAtIndexedSubscript:)
                                        swizzlingSelector:@selector(ht_objectAtIndexedSubscriptI:)];
        });
    }
    
    - (id)ht_objectAtIndexedSubscriptI:(NSUInteger)idx {
        id object = nil;
        @try {
            object = [self ht_objectAtIndexedSubscriptI:idx];
        } @catch (NSException *exception) {
            [HTCrashReporter ht_catchException:exception withCrashType:HTCrashTypeArrayIndexBeyondBounds];
        } @finally {
            return object;
        }
    }
    

    这里有几点需要注意下:

    • 第一点:交换方法需要写在+load方法里,而且要保证只调用一次(这里不赘述具体原因,有兴趣的小伙伴自行查找);
    • 第二点:我们交换的是对象方法,所以应该调用swizzleInstanceMethod方法而不是swizzleClassMethod方法;
    • 第三点:🌰中的数组是不可变数组,根据控制台输出信息中提示的是__NSArrayI(两道下划线),所以我们要替换的类是NSClassFromString(@"__NSArrayI")
    • 第四点:有的小伙伴可能会有疑问,为什么在交换的方法里还要调用当前方法,这不就死循环了吗?非也,这里看上去调用当前方法,但是实质上内部方法的实现是系统方法的实现,所以这里使用了try catch语句,因为数组越界,系统方法会抛出异常,这里捕获异常再做进一步处理,比如上传服务器。到这里就实现了拦截了数据越界引起的崩溃,程序不会闪退还是可以正常运行。

    上面只是一个简单的🌰,HTCrashReporter做了NSString,NSArray,NSDictionary,NSObject常见崩溃拦截,欢迎各位大佬指正,不介意动动手指请赏个Star。

    相关文章

      网友评论

          本文标题:iOS 感受黑魔法Method Swizzling的魅力(二)

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