第二阶段:动态方法解析
-
流程图
-
代码展示
void c_other(id self, SEL _cmd) {
NSLog(@"%s",__func__);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSLog(@"%s", __func__);
if (sel == @selector(test)) {
Method otherMethod = class_getInstanceMethod(self, @selector(other));
class_addMethod(self, sel, (IMP)c_other, "v16@0:8");
return YES;
}
return [super resolveInstanceMethod:sel];
}
- 重点详解下class_addMethod方法,我看网上别人的很多博客,博主自己都没搞明白到底是怎么回事!希望我下面的总结能帮助到你!
class_addMethod(Class _Nullable __unsafe_unretained cls,
SEL _Nonnull name,
IMP _Nonnull imp,
const char * _Nullable types)
第一个参数:如果是实例对象方法,这里就传类对象;
(是自己,就传self,是别的类,就传别的类)
如果是类对象方法,这里就传元类对象;
(是自己,就传元类对象object_getClass(self)是别的类,就传别的元类对象object_getClass(otherClass))
第二个参数:SEL 类型即可
第三个参数:如果是C语言函数,就传(IMP)C语言函数名
如果是OC函数,先通过Method otherMethod = class_getClassMethod(self, @selector(other1:));获取方法名
再传method_getImplementation(otherMethod)
第四个参数:[请先参考这篇文章第2章节](https://blog.youkuaiyun.com/JH_Cao/article/details/122358985)
void类型,传先传一个v
因为OC方法都有两个隐藏的参数(id self, SEL _cmd),
所以再传@,表示id类型或一个object(即对象类型)
再传冒号一个: 表示SEL类型
- 举例说明
1.添加C语言函数
void c_other() {
NSLog(@"%s",__func__);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(test)) {
class_addMethod(self, sel, (IMP)c_other, "v@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
2.添加OC对象方法
- (void)other {
NSLog(@"%s",__func__);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(test)) {
Method otherMethod = class_getInstanceMethod(self, @selector(other));
class_addMethod(self, sel, method_getImplementation(otherMethod), "v@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
3.添加OC类方法
+ (void)other1:(NSString *)str {
NSLog(@"%s",__func__);
}
+ (BOOL)resolveClassMethod:(SEL)sel {
if (sel == @selector(test1)) {
Method otherMethod = class_getClassMethod(self, @selector(other1:));
class_addMethod(object_getClass(self), sel, method_getImplementation(otherMethod), "v@:@"); // NSString 是一个对象类型
return YES;
}
return [super resolveClassMethod:sel];
}