新建一个类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. 解释mysql 语句

    一.在我们创建mysql数据库的时候我们经常会用到这句SQL: CREATE DATABASE TEST DEFAULT CHARACTER SET utf8 COLLATE utf8_general ...

  2. list 列表 函数的引用

    方法 意义 L.index(v [, begin[, end]]) 返回对应元素的索引下标, begin为开始索引,end为结束索引,当 value 不存在时触发ValueError错误 L.inse ...

  3. SURF算法源代码OPENSURF分析

    SURF算法源代码分析 平台:win x64 + VS2015专业版 +opencv2.4.11 配置类似参考OPENSIFT,参考我的另一篇博客:https://www.cnblogs.com/Al ...

  4. Delphi 编写线程的清除代码

  5. (二十四)Ubuntu16.04配置ADB调试环境

    一.安装adb 1.可以通过 apt-get install android-tools-adb 来安装adb sudo add-apt-repository ppa:nilarimogard/web ...

  6. 菜单项(Menu)的初步认识 以及 多级菜单(SubMenu)的初步认识

    MainActivity.class public class MainActivity extends AppCompatActivity { private TextView textView; ...

  7. BIgDecimal输出时添加金额分割符

    1.创建Serializer文件 2.修改输出方法 3.使用

  8. Zabbix trigger(触发器)设置

    设置一个监控项–进站包数,当进站包数>50触发器报警. 先设置一个进站包数的监控项(item):

  9. adreno的tbdr

    看完apple的(&&powervr) 再来撸高通的.. FlexRender 能自己选三种模式 Direct Binning 这个只是分块 HWVizBinning 这个估计就是tb ...

  10. struts2之多文件上传与拦截器(8)

    前台jsp <s:form action="uploadAction" enctype="multipart/form-data" method=&quo ...