iOS 防止方法未实现造成的崩溃
实现原理基于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