美文网首页iOS底层技术
Runtime拦截可变数组replaceObjectAtInde

Runtime拦截可变数组replaceObjectAtInde

作者: wg刚 | 来源:发表于2019-06-10 16:41 被阅读0次
    1、故意写一个相关崩溃代码
    //拦截1
    NSMutableArray *arr1 = @[@"1"].mutableCopy;
    [arr1 replaceObjectAtIndex:5 withObject:@"2"];
    
    //拦截2
    NSMutableArray *arr2 = @[].mutableCopy;
    [arr2 replaceObjectAtIndex:5 withObject:@"1"];
    
    //拦截3
    NSMutableArray *arr3 = @[@"1", @"2"].mutableCopy;
    [arr3 replaceObjectAtIndex:0 withObject:nil];
    
    2、方法交换拦截
    #import "NSMutableArray+HuAvoidCrash.h"
    #import <objc/message.h>
    
    @implementation NSMutableArray (HuAvoidCrash)
    
    +(void)load{
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            
            Class class = NSClassFromString(@"__NSArrayM");
            Method old = class_getInstanceMethod(class, @selector(replaceObjectAtIndex:withObject:));
            Method new = class_getInstanceMethod(class, @selector(hu_replaceObjectAtIndex:withObject:));
    
            if (old && new) {
                method_exchangeImplementations(old, new);
            }
            
        });
    }
    
    -(void)hu_replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
        
        if (self.count-1 >= index && anObject) {
            
            [self hu_replaceObjectAtIndex:index withObject:anObject];
        }else{
        }
    }
    
    @end
    
    3、运行结果

    发现拦截1成功,但是拦截2无效,最终奔溃。(但是也走进了这个拦截方法)

    4、原因

    看下图:断点走进了33行;导致崩溃
    但是self确实0个元素;index是5;

    为什么呢?

    因为:NSUInteger的问题,NSUInteger是无符号的,没有负数

    5、解决方案:
    -(void)hu_replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
        
        if (self.count > index && anObject) {
            
            [self hu_replaceObjectAtIndex:index withObject:anObject];
        }else{
        }
    }
    

    相关文章

      网友评论

        本文标题:Runtime拦截可变数组replaceObjectAtInde

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