二、移魂大法

使用runtime还可以交换两个函数。先贴上代码和执行结果。

#import <Foundation/Foundation.h>

@interface DZLPerson : NSObject

@property(nonatomic,weak)NSString *name;
@property(nonatomic,assign)NSInteger age; -(void)test_inPerson; @end
#import "DZLPerson.h"

@implementation DZLPerson

-(void)test_inPerson
{
NSLog(@"%s",__func__);
} @end

以上是person类,下面还是以之前的那个分类作为例子

#import "DZLPerson.h"

@interface DZLPerson (Job)

@property(nonatomic,copy)NSString* job;

-(void)test_inCategory;

@end
#import "DZLPerson+Job.h"
#import <objc/runtime.h> static NSString *key=@"dzl"; //利用静态变量地址唯一不变的特性 @implementation DZLPerson (Job) -(void)test_inCategory
{
NSLog(@"%s",__func__);
} -(void)setJob:(NSString *)job
{ objc_setAssociatedObject(self, &key, job, OBJC_ASSOCIATION_COPY);
} -(NSString *)job
{
return objc_getAssociatedObject(self, &key);
} @end

下面是执行的主函数

- (void)viewDidLoad
{
[super viewDidLoad]; Method m1=class_getInstanceMethod([DZLPerson class], @selector(test_inPerson));//获取<span style="font-family: Arial, Helvetica, sans-serif;">DZLPerson类中的test_inPerson方法</span> Method m2=class_getInstanceMethod([DZLPerson class], @selector(test_inCategory));//同理 method_exchangeImplementations(m1, m2); DZLPerson *person=[[DZLPerson alloc] init];
[person test_inCategory]; }

执行结果如下:

2015-04-10 23:02:11.954 runtime讲解[10564:507514] -[DZLPerson test_inPerson]



我们会发现,两个test方法的实现被交换了。当我们调用test_inCategory方法时,执行的却是test_inPerson。以上的代码很简单,相信大多数人都能看懂,这里我就不一一解释了,看一下runtime函数名字就知道它的作用了。其实我想说的是,它为什么就交换了呢?下面我用图片来解释一下。

当我们调用方法的时候,系统会首先找到这个方法的SEL ,然后根据SEL所对应的IMP 去执行方法。所有名字相同的方法都对应着同一个SEL ID。那么如果有多个类中都实现了同一个名字的方法,那么系统是怎么区分执行呢?比如A类实现了test 方法,B类也实现了test方法,那么A类对象和B类对象都执行test方法时,到底执行哪个IMP对应的方法呢?这就涉及到了对象的isa指针。每个对象都有一个isa 指针,指向对象的类。那么系统根据isa 指针区分对象所要执行的方法,这样就不会错乱了。

IOS 高级开发 runtime(二)的更多相关文章

  1. IOS高级开发 runtime(一)

    一. 简介 IOS 开发中灵活使用runtime 会提高我们的程序性能和开发速度.要想使用runtime,首先要引入系统的头文件. <span style="font-size:18p ...

  2. iOS 高级开发 runtime(三)

    三 .动态添加方法 我们可以通过runtime动态地添加方法.那么到底啥叫动态添加方法呢?动态添加方法就是当我们程序运行时才知道我们应该调用哪个方法.我们首先需要了解这一点,当我们编写完一段代码后,我 ...

  3. (转发)IOS高级开发~Runtime(二)

    一些公用类: @interface ClassCustomClass :NSObject{ NSString *varTest1; NSString *varTest2; NSString *varT ...

  4. (转发)IOS高级开发~Runtime(四)

    用C代替OC: #import <objc/runtime.h> #import <objc/message.h> #import <stdio.h> extern ...

  5. (转发)IOS高级开发~Runtime(三)

    11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selec ...

  6. (转发)IOS高级开发~Runtime(一)

    IOS高级开发-Runtime(一) IOS高级开发-Runtime(二) IOS高级开发-Runtime(三) IOS高级开发-Runtime(四) 一些公用类: @interface Custom ...

  7. iOS蓝牙开发(二)蓝牙相关基础知识

    原文链接: http://liuyanwei.jumppo.com/2015/07/17/ios-BLE-1.html iOS蓝牙开发(一)蓝牙相关基础知识: 蓝牙常见名称和缩写 MFI ====== ...

  8. IOS高级开发之多线程(四)NSOperation

    1.什么是NSOperation,NSOperationQueue? NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且线程安全的建立状态,优先级,依赖和取消等操作. ...

  9. IOS高级开发~Runtime(二)

    #import <Foundation/Foundation.h> @interface CustomClass : NSObject { NSString *varTest1; NSSt ...

随机推荐

  1. Java笔记(四)……常量与变量

    常量 常量表示不会改变的数值. Java中常量的分类: 整数常量:所有整数 小数常量:所有小数 布尔型常量:较为特有,只有两个数值,true false 字符常量:将一个数字字母或者符号用单引号(' ...

  2. bzoj 2707 [SDOI2012]走迷宫(SCC+高斯消元)

    Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿 ...

  3. vijosP1359 Superprime

    vijosP1359 Superprime 链接:https://vijos.org/p/1359 [思路] 搜索+数学. 很明显的搜索,依次确定每一个数,用参数sum记录dfs即可. 本题的关键在于 ...

  4. HW5.10

    public class Solution { public static void main(String[] args) { int count = 0; for(int i = 1; i < ...

  5. RIA算法解决最小覆盖圆问题

    一.概念引入         最小包围圆问题:对于给定的平面上甩个点所组成的一个集合P,求出P的最小包围圆,即包含P中所有点.半径最小的那个圆.也就是求出这个最小 包围圆的圆心位置和半径.       ...

  6. java 关于多态的一点总结

    http://www.cnblogs.com/wenruo/p/5352683.html 一直不是很理解多态,今天看了两遍<think in java>第八章,试着总结一下. 多态的本质就 ...

  7. devexpress中gridcontrol头部添加垂直线(右边框)

    winform开发,用devexpress中的gridcontrol控件,头部默认是3D样式,当客户希望像内容一样扁平化显示且需要添加垂直线(右边框)时恶梦开始了..经过一阵摸索发现可以这样解决: 1 ...

  8. openCV 2.4.13 iOS background_segm.hpp 'list' file not found

    最近下载了最新版的OpenCV的Framework. 导入到项目里边,编译.然后就出现了问题 /opencv2.framework/Headers/video/background_segm.hpp: ...

  9. JBPM数据库表说明

    http://blog.163.com/tigerlion@126/blog/static/167675665201072642627400/ 最近这几天一直在研究JBPM工作流引擎,以下为JBMP的 ...

  10. validatebox实现多重规则验证

    作为Easyui的校验插件没有实现多重校验能力是一种缺憾.比如说,既要限制格式为email,同时要求最长长度为20,我们就要扩展一种规则,而对长度的要求很容易变化,如果变成要求30,我们又得扩张一种规 ...