iOS在调用未实现的方法时会造成程序Crash的问题,其实在Crash之前程序会查看改类有没有实现如下两个方法,如果实现了两方法就会先调用下面的两个方法
//调用实例方法没有找到会走这个方法
+ (BOOL)resolveClassMethod:(SEL)sel
//调用类方法没有找到会走这个方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
那么为避免程序Crash,可以实现上面两个方法,然后通过runtime动态为该类添加实现,返回YES表示已处理,NO表示为处理,在没有添加实现时,直接返回YES也是会Crash的,具体实现如下:
void dynamicMethodIMP(id self, SEL _cmd) {
NSLog(@" >> 动态实现");
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
IMP imp = dynamicMethodIMP;
#pragma clang diagnostic pop
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
if (sel == @selector(wode)) {
NSLog(@"resolveInstanceMethod-sel==%@",NSStringFromSelector(sel));
// class_addMethod(Class _Nullable __unsafe_unretained cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types)
//最后表示这个c函数的返回以及各个参数类型,具体意义查看
//https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100
class_addMethod(self, @selector(wode), imp, "v@:");
return YES;
}
#pragma clang diagnostic pop
return [super resolveInstanceMethod:sel];
}
+ (BOOL)resolveClassMethod:(SEL)sel{
return [super resolveClassMethod:sel];
}
注意
class_addMethod()方法只能添加实例方法,无法添加类方法详细见官方文档如下:
官方文档