动态添加方法:
动态添加就运用到懒加载
开发场景:如果一个类方法很多,加载类到内存的时候也比较耗费资源,需要给每个方法生成一个映射表(这个词我也不懂),可以使用动态给某个类添加方法。
Person *p = [[Person alloc]init];
//performSelector:即为动态添加方法
[p performSelector:@selector(eat) withObject:nil];
// 会报警告,运行后会报错,报的错误是因为你没有在Person类里面实现eat方法
如果你想自己动态添加方法
首先你要在类中实现代码如下:
#首先介绍相关的方法,后面再整合
/**
处理实例方法
动态添加方法,首先实现这个resolveInstanceMethod方法
resolveInstanceMethod调用的情况:当调用了一个没有实现的方法,就会调用resolveInstanceMethod这个方法
<#sel#>:没有实现的方法
*/
+ (BOOL)resolveInstanceMethod:(SEL)sel{}
// runtime 方法(导入<objc/message.h>)
class_addMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>, <#IMP imp#>, <#const char *types#>)
<#__unsafe_unretained Class cls#>:表示给哪个类添加 -- self
<#SEL name#>:方法编号 即为 方法名 -- 未实现的方法
<#IMP imp#> :方法的实现,函数入口,函数指针或函数名 --在本类的@implementation 类名 下面
// 定义一个函数(函数名随便写,IMP要与之一致)
void tangtang_eat(){
}
<#const char *types#> :方法的类型 ---查看xcode help document文档
xcode --> help --> document -->搜索runtime --> 方法class_addMethod --> 查看<#const char *types#>用法(也有整个动态添加方法的描述)
#根据苹果系统的东西来
#import "Person.h"
#import <objc/message.h>
@implementation Person
/**
默认一个方法都有两个参数,self,_cmd,为隐式参数,不显示
self :方法的调用者
_cmd :调用方法的编号,即方法名
*/
//1. 定义一个函数(函数名随便写)
// 无返回值,参数(id,SEL)
void tangtang_eat(id self, SEL _cmd){
NSLog(@"调用糖糖的eat方法 %@ %@",self,NSStringFromSelector(_cmd));
}
/**
2.处理为实现的实例方法
动态添加方法,首先实现这个resolveInstanceMethod方法
resolveInstanceMethod调用的情况:当调用了一个没有实现的方法,就会调用resolveInstanceMethod这个方法
<#sel#>:没有实现的方法
*/
+ (BOOL)resolveInstanceMethod:(SEL)sel{
// 动态添加未实现的方法
if (sel == @selector(eat)) {
/**
v : void
@ : 对象
: : SEL
*/
class_addMethod(self, sel, (IMP)tangtang_eat, "v@:");
// 处理完
return YES;
}
return [super resolveInstanceMethod:sel];
}
@end
#在viewController中
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [[Person alloc]init];
//performSelector:即为动态添加方法
[p performSelector:@selector(eat)];
}
输出日志
#如果你要实现带有参数的(自己找两者的不同)
#Person.m文件中
// C语言中所有对象类型用 id
void tangtang_eat(id self, SEL _cmd, id prame1){
NSLog(@"调用糖糖的eat方法 %@ %@ %@",self,NSStringFromSelector(_cmd),prame1);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{
// 动态添加未实现的方法
if (sel == @selector(eat:)) {
/**
v : void
@ : 对象
: : SEL
*/
class_addMethod(self, sel, (IMP)tangtang_eat, "v@:@");
// 处理完
return YES;
}
return [super resolveInstanceMethod:sel];
}
#ViewControllers中
[p performSelector:@selector(eat:) withObject:@11];
输出日志,注意最后的11数字
网友评论