zoukankan      html  css  js  c++  java
  • runtime认识及其用处

    1、什么是运行时(runtime):

    1> runtime是一套底层的C语言API(包含很多强大实用的C语言数据类型、C语言函数)

    2> 实际上,平时我们编写的OC代码,底层都是基于runtime实现的

    * 也就是说,平时我们编写的OC代码,最终都是转成了底层的runtime代码(C语言代码)

    2、运行时(runtime)有啥好处:

    runtime有啥用?

    1> 能动态产生一个类、一个成员变量、一个方法

    2> 能动态修改一个类、一个成员变量、一个方法

    3> 能动态删除一个类、一个成员变量、一个方法

    3常见的函数、头文件

    #import <objc/runtime.h> : 成员变量、类、方法
    
    Ivar * class_copyIvarList : 获得某个类内部的所有成员变量
    
    Method * class_copyMethodList : 获得某个类内部的所有方法
    
    Method class_getInstanceMethod : 获得某个实例方法(对象方法,减号-开头)
    
    Method class_getClassMethod : 获得某个类方法(加号+开头)
    
    method_exchangeImplementations : 交换2个方法的具体实现
    
    #import <objc/message.h> : 消息机制
    
    objc_msgSend(....)

    4、运行时的(runtime)运用

         4.1 获取所有成员属性

         4.1.1 自定义一个类:

    #import <Foundation/Foundation.h>
    
    @interface ICKPerson : NSObject
    
    /** 年龄 */
    @property (nonatomic,assign) NSInteger age;
    
    /** 姓名 */
    @property (nonatomic,copy) NSString * name;
    
    /** 身高 */
    @property (nonatomic,assign) float height;
    
    
    
    /** 方法 */
    - (void)eat;
    - (void)read;
    @end
    
    @implementation ICKPerson
    - (void)eat{}
    - (void)read{}
    @end

          4.1.2 获取成员属性:

    #import "ViewController.h"
    #import "ICKPerson.h"
    #import <objc/runtime.h>
    @interface ViewController ()
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 获取一个类的所有成员属性
        unsigned int count = 0;
        Ivar *ivars = class_copyIvarList([ICKPerson class], &count);
        for (int i = 0; i<count; i++) {
            Ivar ivar = ivars[i];
            // 获取属性名
            const char *name = ivar_getName(ivar);
            // 获取属性类型
            const char *class = ivar_getTypeEncoding(ivar);
            NSLog(@"name:%s   class:%s",name,class);
        }
        // 释放ivars---C语言的在ARC中通过copy产生,需要手动释放
        free(ivars);
    }
    @end

          4.1.3 测试结果打印:

          4.2 获取其所有内部方法

        // 获取一个类的所有方法
        unsigned int count = 0;
        Method *methods = class_copyMethodList([ICKPerson class], &count);
        for (int i = 0; i<count; i++) {
            // 取出对应的i 位置方法
            Method method = methods[i];
           SEL sel = method_getName(method);
            NSLog(@"%@",NSStringFromSelector(sel));
        }
        free(methods);

         打印结果:

         4.3  交换两个方法的具体实现

         4.3.1 交换方法

    #import "ICKPerson.h"
    
    #import <objc/runtime.h>
    
    @implementation ICKPerson
    
    + (void)load
    {
       // 交换吃和度的方法
        Method m1 = class_getInstanceMethod(self, @selector(eat));
        Method m2 = class_getInstanceMethod(self, @selector(read));
        method_exchangeImplementations(m1, m2);
    }
    
    - (void)eat{
        NSLog(@"---eat");
    }
    
    - (void)read{
         NSLog(@"---read");
    }
    @end

          4.3.2 实现吃方法:

    - (void)viewDidLoad {
        [super viewDidLoad];
        ICKPerson *person = [[ICKPerson alloc] init];
        [person eat];
    }

          // 打印结果

          4.3.3 实现读方法:

    - (void)viewDidLoad {
        [super viewDidLoad];
        ICKPerson *person = [[ICKPerson alloc] init];
        [person read];
    }

          // 打印结果

  • 相关阅读:
    前端技术学习路线及技术汇总
    周末学习笔记——B/S和C/S的介绍
    前端个人笔记----------vue.js
    js中闭包来实现bind函数的一段代码的分析
    零碎总结
    最近要做的事
    递归中的返回
    近期写js库中遇到的一个判别的问题
    js中函数的写法
    关于异步回调的一段代码及相关总结
  • 原文地址:https://www.cnblogs.com/jfckliving/p/4777612.html
Copyright © 2011-2022 走看看