runtime - 动态添加方法

来源:互联网 发布:java流媒体服务器 编辑:程序博客网 时间:2024/05/01 18:50

动态添加方法:
动态添加就运用到懒加载
开发场景:如果一个类方法很多,加载类到内存的时候也比较耗费资源,需要给每个方法生成一个映射表(这个词我也不懂),可以使用动态给某个类添加方法。

 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语言中所有对象类型用 idvoid 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数字

添加方法完结,晚安,好梦

0 0
原创粉丝点击