• IOS 高级开发 runtime(二)


    二、移魂大法

    使用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 指针区分对象所要执行的方法,这样就不会错乱了。




  • 相关阅读:
    windbg 内核模式调试用户进程
    深发展银行编码器(解剖)
    SIM300常用命令
    tdi驱动 for vista or later
    vm命令行控制 (vmrun)
    WMI事件监控
    Visual C++ 中 #pragma 指示符的使用
    IOCP开发的几个概念
    移动web.config文件时造成的错误,
    提高网站速度|页面优化
  • 原文地址:https://www.cnblogs.com/dengzhuli/p/4423586.html
Copyright © 2020-2023  润新知