新建一个类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. Qt 中配置 c99的问题

    Qt 5.3 版本 报错原因是c99标准问题的话,可以尝试下面方法 打开项目中xxx.pro工程文件 加入如下语句: QMAKE_CFLAGS += -std=c99

  2. Flutter——Row组件(水平布局组件)

    Row组件的常用属性 属性 说明 mainAxisAlignment 主轴的排序方式 crossAxisAlignment 次轴的排序方式 children 组件子元素 import 'package ...

  3. VMware无法连接MKS:套接字连接尝试次数太多解决

    粘贴自:https://jingyan.baidu.com/article/425e69e61eb578be15fc16ae.html VMware在开启虚拟机的时候,突然弹出[无法连接MKS:套接字 ...

  4. (二)线程Thread中的方法详解

    1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...

  5. drf 第一节

    drf django-restframework ''' 1.接口:接口的概念.数据接口文档.接口规范(restful).Postman接口测试工具 2.drf请求生命周期 - CBV 3.drf的基 ...

  6. numba初体验

    numba初体验 今天在知乎上发现了一个很神奇的包numba,可以用jit的方式大幅提高计算型python代码的效率,一起来看一下 安装 numba的安装方式很简单,使用pip或者anacoda都可以 ...

  7. i3wm脚本

    exec 执行命令 --no-startup-id 有些脚本或者程序不支持启动通知,不加命令,鼠标会长时间空转,60秒左右 exec_always 每次重启i3,使用该命令启动的程序都会重新执行一次, ...

  8. 【luoguP1955 】[NOI2015]程序自动分析--普通并查集

    题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3...代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变 ...

  9. AGC032F One Third

    很奇怪的一个题.看见了无从下手.概率期望好题. 给一个面积为 \(1\) 的圆,经过圆心随机幅角切直径 \(n\) 次,定义 \(f(x) = \min |S - \frac{1}{3}|\),其中 ...

  10. 网络层中的 IP 协议

    IP协议 IP(IPv4.IPv6)相当于 OSI 参考模型中的第3层——网络层.网络层的主要作用是“实现终端节点之间的通信”.这种终端节点之间的通信也叫“点对点通信”. 网络的下一层——数据链路层的 ...