ios-动态添加方法,交换方法,重定向方法
2024-08-30 06:59:23
新建一个类Person,Person.h 不写代码,Person.m 有如下两个方法:
- (void)eat
{
NSLog(@"xxx eat====");
}
【动态添加方法】
尝试在 Person 类里添加一个 run 的实例方法。加上如下两个方法即可:
void run(id self, SEL sel, NSString *str) {
NSLog(@"xxx run==%@", str);
} // 只要调用了该类未实现的方法,就会来到这个方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
BOOL isSucess = NO;
if (sel == @selector(run:)) {
isSucess = class_addMethod(self, sel, run, "v@:@");
}
return isSucess;
}
然后调用运行和打印如下:
Person *p = [Person new];
[p performSelector:@selector(run:) withObject:@"222xxxxxxxxxxx"]; // log: xxx run==222xxxxxxxxxxx
在 ios调用私有方法 中有提到如何打印一个类下的方法 ,这里调用测试如下
[self getMethods]; Person *p = [Person new];
[p performSelector:@selector(run:) withObject:@"222xxxxxxxxxxx"]; [self getMethods];
打印如下:
=============
方法名= eat
参数类型= @
参数类型= :
返回类型值类型= v
xxx run==222xxxxxxxxxxx
=============
方法名= run:
参数类型= @
参数类型= :
参数类型= @
返回类型值类型= v
=============
方法名= eat
参数类型= @
参数类型= :
返回类型值类型= v
从上面这个打印也可以看出,当没有调用这个方法时,打印 Person 类下方法只有eat一个;当调用了 run 方法后,这个方法就被添加到 Person 类的 methodlist 里了。
【交换方法】
在 Person.m 中加一个 -sleep 方法
- (void)eat
{
NSLog(@"xxx eat====");
} - (void)sleep
{
NSLog(@"xxx sleep===");
}
可以在 Person 的 + load 方法中进行方法交换,因为一个类的 +load 方法在该类载入内存时就会开始调用。
+ (void)load
{
Method m1 = class_getInstanceMethod(self, @selector(sleep));
Method m2 = class_getInstanceMethod(self, @selector(eat));
method_exchangeImplementations(m1, m2);
}
调用 run: 方法和打印如下: (从打印可以发现,方法已经被替换了)
Person *p = [Person new];
[p performSelector:@selector(sleep)]; // log: xxx eat====
[p performSelector:@selector(eat)]; // log: xxx sleep===
【重定向方法】
在 Person.m 中 + load 方法如下: (意思是将sleep方法编号定向到eat方法的实现中)
+ (void)load
{
Method m1 = class_getInstanceMethod(self, @selector(sleep));
IMP imp = class_getMethodImplementation(self, @selector(eat));
method_setImplementation(m1, imp);
}
调用打印如下:(可以看到最终两个方法都进入eat)
Person *p = [Person new];
[p performSelector:@selector(sleep)]; // log: xxx eat====
[p performSelector:@selector(eat)]; // log: xxx eat====
最新文章
- for循环中的 else,break
- Razor 模板自己渲染出结果 string
- 推薦使用 Microsoft Anti-Cross Site Scripting Library V3.0
- BS架构与CS架构的区别
- global 用法
- TCP/IP 编程
- 2016最新cocoapods版本更新,以及多个版本的问题
- MVC3.0,路由设置实现伪静态IIS中404错误
- TabHost 简单用法
- Redis 的性能幻想与残酷现实(转)
- 单源最短路Dijkstra算法——matlab实现
- k8s搭建rook-ceph
- P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
- C++ Exception机制
- 标准I/O的缓冲
- Vue-Vue文本渲染三种方法 {{}}、v-html、v-text
- eclipse svn同步资源库时忽略某些不需要提交文件类型和文件夹
- css文件放在根目录之后不起作用原因
- 自然语言交流系统 phxnet团队 创新实训 个人博客 (五)
- CRLF LF CR