二、移魂大法

使用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. 【原】 Spark中Task的提交源码解读

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Stage的提交 http://www.cnblogs.com/yourarebest/p/5356769.html Spark中 ...

  2. 微软 Build 2014开发者大会干货整理-1

    微软 Build 2014开发者大会第二天的主题演讲主要包含两部分:Microsoft Azure的发展状况,以及 .NET和生态系统的发展介绍.第二天的重点整理也由此分为上下两部分.您可以在Chan ...

  3. java项目中eclipse控制台输出log4j的信息

    最近做的一个hadoop项目中,用MR实现了一个比较复杂的问题,其中的日志信息都是使用的是log4j来处理的.但不知怎么控制台不输出日志信息,只能输出System.out.println()信息,这个 ...

  4. Zookeeper集群安装详解

    Zookeeper的角色   Zookeeper集群搭建 要求:服务器集群规模不小于3个节点,各服务器之间系统时间要保持一致! 安装步骤 1.在h1节点解压,目录改名. tar –zxvf zooke ...

  5. Robotium学习笔记二

    一. 控制测试用例的执行顺序 采用TestSuit方式来控制每条Case的运行顺序 Demo如下 public static Test suite() { TestSuite suite = new ...

  6. 工作7年,从《一个苏州IT人的5年挨踢经历》系列开始,博客1年半,纯纪念

    真正涉足CSDN,还是从<一个苏州IT人的5年挨踢经历>系列的发帖开始,当时大家比较捧场,遂把帖子内容整理,其后创建CSDN博客并发表于其上.有了这个开端,后续就习惯性的开始在CSDN写技 ...

  7. 【python自动化第十篇:】

    复习: 线程与进程的区别: 进程:资源的集合 线程:最小调度单位 进程至少包含一个线程 线程之间的内存是共享的,两个线程操作同一个数据就会修改整个结果(需要mutex加锁来保持数据的一致性),递归锁, ...

  8. Install Package and Software

    svn http://tortoisesvn.sourceforge.net/ git https://download.tortoisegit.org/ http://git-for-windows ...

  9. 基于smack的xmpp packet 重写

    基于Smack 实现Notification数据包.smack的类中有一个org.jivesoftware.smack.packet.IQ只需对他重写即可,在做的时候其实可以简单一点的,如果你使用ti ...

  10. [Webpack 2] Add Code Coverage to tests in a Webpack project

    How much of your code runs during unit testing is an extremely valuable metric to track. Utilizing c ...