新建一个类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====

最新文章

  1. for循环中的 else,break
  2. Razor 模板自己渲染出结果 string
  3. 推薦使用 Microsoft Anti-Cross Site Scripting Library V3.0
  4. BS架构与CS架构的区别
  5. global 用法
  6. TCP/IP 编程
  7. 2016最新cocoapods版本更新,以及多个版本的问题
  8. MVC3.0,路由设置实现伪静态IIS中404错误
  9. TabHost 简单用法
  10. Redis 的性能幻想与残酷现实(转)
  11. 单源最短路Dijkstra算法——matlab实现
  12. k8s搭建rook-ceph
  13. P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
  14. C++ Exception机制
  15. 标准I/O的缓冲
  16. Vue-Vue文本渲染三种方法 {{}}、v-html、v-text
  17. eclipse svn同步资源库时忽略某些不需要提交文件类型和文件夹
  18. css文件放在根目录之后不起作用原因
  19. 自然语言交流系统 phxnet团队 创新实训 个人博客 (五)
  20. CRLF LF CR

热门文章

  1. java集合之hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升
  2. UART串口简介
  3. 基于SAML2.0的SAP云产品Identity Authentication过程介绍
  4. 使用nodejs实现OData的batch操作在Marketing Cloud里读取contact信息
  5. navicat for mysql 下载安装教程
  6. Linux学习笔记(五)Linux常用命令:压缩命令
  7. RNN基础
  8. ServiceLoader在SPI中的重要作用分析
  9. PAT乙级1038
  10. linux基础_用户管理