美文网首页
RunTime实现

RunTime实现

作者: i玉米炖排骨 | 来源:发表于2018-04-11 11:21 被阅读0次

    1:RunTiem交换方法实现

        //runTime交换方法实现

        // 1,创建已有类的分类,并且实现自己的方法

    //    @implementation UIImage (image)

    //    +(UIImage *)ym_imageNamed:(NSString *)name

        // 2,在类方法load里面用runtime获取该类原来方法和自己实现的方法

        // 3,用run time交换方法实现,注意这里是方法指针的交换,需要注意的是别调错方法,发生死循环

    //    +(void)load

    //    {

    //        // 交换方法的实现,方法都是定义在类里

    //        //    class_getMethodImplementation 获取方法实现

    //        //    method_getImplementation(<#Method m#>)

    //        //    class_getClassMethod表示获取类方法

    //        //    class_getInstanceMethod获取一个对象方法

    //        //    class:获取哪个类方法

    //        Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));

    //        Method ym_imageNameMethod = class_getClassMethod([UIImage class], @selector(ym_imageNamed:));

    //        //交换方法实现,实际上是修改了方法指针

    //        method_exchangeImplementations(imageNameMethod, ym_imageNameMethod);

       }

        //使用方法

        UIImage *image = [UIImage imageNamed:@"1232"];

    2:RunTime动态添加方法

      创建一Person类,给该类动态添加方法。

      //ViewController.m

    (1)#import "ViewController.h"

       #import “Person.h"

    - (void)viewDidLoad {

        [super viewDidLoad];

        Person *p = [[Person alloc] init];

        // 动态添加无参数的方法

        [p performSelector:@selector(eat)];

    }

    (2)Person.m文件

    #import "Person.h"

    #import

    @implementation Person

    //定义函数

    //默认一个方法都有两个参数,self,_cmd,这叫隐式参数

    //self:方法调用者

    //_cmd:调用方法的编号

    void aaaa (id self, SEL _cmd){

        NSLog(@"调用了eat这个函数%@%@",self,NSStringFromSelector(_cmd));

    }

    // 动态添加方法,首先实现resolveInstanceMethod方法

    // resolveInstanceMethod调用:调用了一个没有实现的方法时,就会调用resolveInstanceMethod

    // resolveInstanceMethod作用:

    // sel:没用实现方法

    + (BOOL)resolveInstanceMethod:(SEL)sel

    {

        NSLog(@"---->%@",NSStringFromSelector(sel));

        if (sel == @selector(eat)) {

            /*

             class:给哪个类添加方法

             SEL:添加方法的方法编号是什么

             IMP:方法实现,函数入口,函数名

             type:方法类型

             */

    // "v@:" 查看runTime官方文档 Dynamic Method Resolution和Type Encodings

            //给一个类添加方法

            class_addMethod([self class], sel, (IMP)aaaa, "v@:");

            //表示处理完

            return YES;

        }

       return [super resolveInstanceMethod:sel];

    }

    @end

    3.RunTime动态添加属性

    例如:实现NSObject类别里添加属性(本质是指针间的关联)

    (1)创建NSObject+objc分类,在.h文件中实现:

    @interface NSObject (objc)

    //@property在分类里的作用,只会实现get,set方法的声明,不会去实现。因此需要自己去实现

    @property (strong, nonatomic) NSString *name;

    @end

    (2)在.m文件中实现:

    #import "NSObject+objc.h"

    #import

    static char nameKey;

    @implementation NSObject (objc)

    - (void)setName:(NSString *)name

    {

        /*

         添加属性,跟对象

         给某个对象产生关联,添加属性

         object:给哪个对象添加属性

         key:属性名,根据key去获取关联的对象

         value:关联的值

         policy:关联的策略

         void * == id 

         */

        objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    }

    - (NSString *)name

    {

        return objc_getAssociatedObject(self, &nameKey);

    }

    @end

    (3)ViewController类中使用方法:

        NSObject *obj = [[NSObject alloc] init];

        obj.name = @"1232";

        NSLog(@"----->>%@",obj.name);

    4.RunTime消息机制

    首先创建Person类,并且实现一个类方法,一个对象方法

    //

    //  Person.h

    //  runTime交换方法

    //

    //  Created by YanMacBook on 6/16/16.

    //  Copyright © 2016 YanMacBook. All rights reserved.

    //

    #import

    @interface Person : NSObject

    - (void)eat;

    + (void)eat;

    @end

    .m文件中实现方法

    - (void)eat

    {

        NSLog(@"------对象方法------");

    }

    + (void)eat

    {

        NSLog(@"-----类方法--------");

    }

    使用方法:

        //runTime实例对象调用方法

    //    Person *p = [[Person alloc] init];

    //    objc_msgSend(p, @selector(eat));

        //runTime类对象调用方法

        Class PersonObjc = [Person class];

        objc_msgSend(PersonObjc, @selector(eat));

    相关文章

      网友评论

          本文标题:RunTime实现

          本文链接:https://www.haomeiwen.com/subject/wfeahftx.html