新建一个类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. PropertiesUtils(普遍做法)

    public class PropertiesUtil{ private static Properties properties; static{ InputStream in = null; tr ...

  2. SuperMap iClient3D for WebGL 9D怎么将s3m图层的纹理变更精细些

    设置S3MTilesLayer.lodRangeScale.默认值是1,设的越小越精细,最小值是0.01.越大越模糊,最大值是100

  3. Java虚拟机内存基础、垃圾收集算法及JVM优化

    1 JVM 简单结构图   1.1 类加载子系统与方法区 类加载子系统负责从文件系统或者网络中加载 Class 信息,加载的类信息存放于一块称 为方法区的内存空间.除了类的信息外,方法区中可能还会存放 ...

  4. 【Distributed】大型网站高并发和高可用

    一.DNS域名解析 二.大型网站系统应有的特点 三.网站架构演变过程 3.1 传统架构 3.2 分布式架构 3.3 SOA架构 3.4 微服务架构 四.高并发设计原则 4.1 拆分系统 4.2 服务化 ...

  5. Win7系统不能拖动文件夹的问题怎么解决?

    一般情况下,如果我们想要在电脑中移动文件夹,可以采用剪切复制粘贴或者按住鼠标左键拖动的方式来实现,但有些Win7系统用户反映文件夹会出现不能移动的情况,这是怎么回事呢?下面好系统U盘启动就为大家介绍一 ...

  6. 学习elasticsearch(一)linux环境搭建(1)

    首先安装了Oracle Virtual Box 然后安装了最小版的CentOS.由于vbox自带的操作面板不太好用,于是用了xshell,XShell连接最小版的centOS时遇到的问题记录下. 1. ...

  7. Event Binding in Angular

    https://www.pluralsight.com/guides/angular-event-binding Introduction In this guide, we will explore ...

  8. vue store获取值时 Computed property "activeTag" was assigned to but it has no setter.

    出现原因: element-ui中 el-tab绑定的值在切换tab时会自动修改 而activeTag是从store中获取的值,不能直接修改 要添加给它绑定上set   <el-tabs cla ...

  9. CVE-2018-10933 LibSSH auth bypass

    漏洞原理 认证实现错误, 认证分为多个步骤,可以直接跳到成功的步骤       A vulnerability was found in libssh's server-side state mach ...

  10. python_tkinter组件摆放方式

    1.最小界面组成 # 导入tkinter模块 import tkinter # 创建主窗口对象 root = tkinter.Tk() # 设置窗口大小(最小值:像素) root.minsize(30 ...