iOS runtime swizzle 黑魔法

NSMutableArray数组越界崩溃解决

对一个可变数组操作很频繁,并且在多个线程操作同一个可变数组时,发生数组越界等崩溃是很常见的。所以使用runtime swizzle ,对其方法进行交换。然后在交换方法中对增,删,改,查等做保护机制就可以避免数组越界造成的崩溃。

1.新建一个NSMutableArray的分类

#import

NS_ASSUME_NONNULL_BEGIN

@interfaceNSMutableArray (SafeMutableArray)

@end

NS_ASSUME_NONNULL_END


2.文件实现

需要导入runtime.h文件

#import

然后在load方法中声明进行方法交换声明

+ (void)load

{

    staticdispatch_once_tonceToken;

    dispatch_once(&onceToken, ^{


        idobj = [[selfalloc]init];

        [objswizzleInstanceMethod:@selector(addObject:)withMethod:@selector(m_addObject:)];

        [objswizzleInstanceMethod:@selector(objectAtIndex:)withMethod:@selector(m_objectAtIndex:)];

    });

}

交换方法的实现

- (void)swizzleInstanceMethod:(SEL)origSelector withMethod:(SEL)newSelector {

    Classcls = [selfclass];


    MethodoriginalMethod =class_getInstanceMethod(cls, origSelector);

    MethodswizzledMethod =class_getInstanceMethod(cls, newSelector);


    BOOLdidAddMethod =class_addMethod(cls,

                                        origSelector,

                                        method_getImplementation(swizzledMethod),

                                        method_getTypeEncoding(swizzledMethod));

    if(didAddMethod) {

        class_replaceMethod(cls,

                            newSelector,

                            method_getImplementation(originalMethod),

                            method_getTypeEncoding(originalMethod));

    }else{

        method_exchangeImplementations(originalMethod, swizzledMethod);

    }

}

- (void)m_addObject:(id)anObject

{

    if(nil!= anObject) {

        [selfm_addObject:anObject];

    }

    else

    {

        NSLog(@"这虽然是空数据,但是不会crash");

    }

}

- (id)m_objectAtIndex:(NSUInteger)index

{

    if(index

        return[selfm_objectAtIndex:index];

    }

    else

    {

        NSLog(@"虽然数组越界,但是不会crash");

        returnnil;

    }

}

你可能感兴趣的:(iOS runtime swizzle 黑魔法)