iOS

iOS 防止方法未实现造成的崩溃

2022-03-31  本文已影响0人  码代码的鱼

实现原理基于runtime的方法交换和消息发送机制

方法交换 method_exchangeImplementations 

NSObject添加分类

@implementation NSObject (Forwarding)

static ForwardingTarget *target;

+ (void)load{

    staticdispatch_once_tonceToken;

    dispatch_once(&onceToken, ^{

        target = [ForwardingTarget new];

        MethodoriginalMethod =class_getInstanceMethod([selfclass],@selector(forwardingTargetForSelector:));

        MethodswizzlingMethod =class_getInstanceMethod([selfclass],@selector(customForwardingTargetForSelector:));

        BOOL didAdd = class_addMethod([self class],method_getName(originalMethod) ,method_getImplementation(originalMethod) , method_getTypeEncoding(originalMethod));

        if(didAdd) {

            class_replaceMethod([self class], method_getName(originalMethod), method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));

        }else{

            method_exchangeImplementations(originalMethod, swizzlingMethod);

        }

    });

}

-(id)customForwardingTargetForSelector:(SEL)aSelector{

    id result = [self customForwardingTargetForSelector:aSelector];

    if(result)returnresult;

    returntarget;

}

这个类里主要是交换了系统的forwardingTargetForSelector:方法,转发给ForwardingTarget这个类,而ForwardingTarget类里重写resolveInstanceMethod,动态添加方法

@implementation ForwardingTarget

id newDynamicMethod(id self, SEL _cmd){

    return[NSNullnull];

}

+(BOOL)resolveInstanceMethod:(SEL)sel{

    class_addMethod([selfclass], sel, (IMP)newDynamicMethod,"@@:");

    [super resolveInstanceMethod:sel];

    return YES;

}

@end

上一篇下一篇

猜你喜欢

热点阅读