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

ios-动态添加方法,交换方法,重定向方法的更多相关文章

  1. ios动态添加属性的几种方法

    http://blog.csdn.net/shengyumojian/article/details/44919695 在ios运行过程中,有几种方式能够动态的添加属性. 1-通过runtime动态关 ...

  2. ASP.NET动态添加用户控件的方法

    本文实例讲述了ASP.NET动态添加用户控件的方法.分享给大家供大家参考.具体实现方法如下: 为了让用户控件能ASP.NET页面实现动态添加,首先写一个接口IGetUCable,这个接口有一个函数,返 ...

  3. EasyUI两种动态添加tab Iframe页面的方法

    /** 动态添加tab-----方式一 **/ function addIframeTab(titleTxt,href,icon) { $('#mytabs').tabs('addIframeTab' ...

  4. 原生js动态添加新元素、删除元素方法

    1. 添加新元素 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  5. 动态添加Redis密码认证的方法

    1.定制jedis 对redis返回的错误的处理,做两处修改: 忽略 (error) ERR Client sent AUTH, but no password is set.使配置了密码的jedis ...

  6. jquery 如何动态添加、删除class样式方法介绍

    获取与设置样式 获取class和设置class都可以使用attr()方法来完成.例如使用attr()方法来获取p元素的class 取与设置样式 获取class和设置class都可以使用attr()方法 ...

  7. jquery 如何动态添加、删除class样式方法介绍_jquery_脚本之家

    获取与设置样式 获取class和设置class都可以使用attr()方法来完成.例如使用attr()方法来获取p元素的class 取与设置样式 获取class和设置class都可以使用attr()方法 ...

  8. iOS 运行时使用(交换两个方法)

    举例 在创建了如下代码 NSString *str=nil; NSURL *url =[NSURL URLWithString:str]; NSLog(@"%@",url); 但是 ...

  9. Emit学习(3) - OpCodes - 动态添加属性、构造函数、方法

    上一篇介绍了 IL 的部分, 基础的部分, 暂时就介绍到那里了, 接下来要进入代码编写阶段了. 今天的主题是 在代码运行的过程中, 去动态的创建类, 属性, 方法. 来源:http://www.cnb ...

  10. Jquery 页面元素动态添加后绑定事件丢失方法,非 live

    代码1: 以此方法绑定的input框事件,在通过add按钮后用jquery绑定的事件 alert就会丢失 <input type="button" value="A ...

随机推荐

  1. Spring @Scheduled执行原理解析

    项目使用很多@Scheduled(cron=**) 注解来实现定时任务,既然要用就必须弄清楚的它的实现原理,于是乎翻了一下相关的源码. Spring 3.0之后增加了调度器功能,提供的@Schedul ...

  2. 【atcoder】GP 2 [agc036C]

    题目传送门:https://atcoder.jp/contests/agc036/tasks/agc036_c 题目大意:给你一个长度为$N$初始全0的序列,每次操作你可以找两个不同的元素,一个自增1 ...

  3. 批量kill指定名称的进程

     以Airflow举例: ps -ef | grep “airflow" | grep -v grep | cut -c 9-15 | xargs kill -9   分析: ps -ef  ...

  4. Django—admin系统:admin的使用及源码剖析

    admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTALLE ...

  5. 11_Redis_事务

    一:Redis 事务:目的为了进行Redis语句的批量化操作,不保证数据安全 Redis作为NoSQL数据库也同样提供了事务机制:在Redis中,MULTI/EXEC/DISCARD/这三个命令是我们 ...

  6. Linux入门基础

    计算机及运维介绍 如何学习Linux 要想学好任何一门学问,不仅要眼睛看,耳朵听,还要动手记,勤思考,多交流甚至尝试着去教会别人 1.1 运维核心职责 网站数据不能丢 网站7*24小时运行 提升用户体 ...

  7. 记一次idea后台日志乱码解决办法

  8. GoTests工具自动化test使用

    安装 $go get -u github.com/cweill/gotests/... 复制代码 具体使用示例 用法 $gotests [options] PATH ... 复制代码 options说 ...

  9. 移动端meta常用的设置

    1.qq强制横屏或者竖屏显示    :   <meta name="x5-orientation" content="portrait ||andscape&quo ...

  10. kotlin字符串模板&条件控制

    字符串模版: 小时候都有要求记日记的习惯,下面是一小学生记的日记: 很漂亮的流水账,那细分析一下这些文件其实大体都类似,只有几个不同点: 其实就是地点变了,那对于这种有规律的文字可以采用kotlin的 ...