美文网首页
runtime应用--添加动态类

runtime应用--添加动态类

作者: 过气的程序员DZ | 来源:发表于2020-07-27 02:33 被阅读0次

创建类

因为要使用runtime的api,所以要导入头文件#import <objc/runtime.h>
创建类代码:

//创建
Class Car = objc_allocateClassPair([NSObject class], "Car", 0);
//注册
objc_registerClassPair(Car);

调用了runtime的两个api方法

  • objc_allocateClassPair:创建类

    • 参数1:父类,和我们手动创建类一样,需要指定父类
    • 参数2:类的名字
    • 参数3:通常传0,可以在注释中查看。
  • objc_registerClassPair:注册到内存

    • 参数:创建的类。

添加成员变量

添加成员变量ivar

//创建
Class Car = objc_allocateClassPair([NSObject class], "Car", 0);
//添加成员变量
class_addIvar(Car, "name", sizeof(NSString *), log2(sizeof(NSString *)), "@");
//注册
objc_registerClassPair(Car);

需要注意:class_addIvar在objc_allocateClassPair和objc_registerClassPair两个api调用之间添加。因为类在编译期需要确认空间大小,成员变量是需要被计算到初始大小中。所以需要在加载内存之前就得加入到类中。

成员变量其实存储在类结构体中ro中,ro就是read only,只读的状态。为什么要有‘只读’的这一部分呢?我们都知道OC是动态语言,可以对类增加方法、属性等操作。但是原始类中的方法和属性等信息,首先需要保存到一个只读的区域内,然后在复制到rw(可读写的)区域内。这样的好处是:当动态增加新的方法和属性的时候,直接操作rw区域就可以了。在查找方法的时候,也只在rw读取就可以了。而且ro区域中的内容给不会变动,保证不会被数据‘污染’。ro和rw的关系,可以参考下图:红色标记出来的就是rw和ro


添加属性

添加属性需要注意一些内容:

  1. 类的属性是有属性的,例如:@property (copy, nonatomic) NSString *subName;中括号的部分就是类属性的属性。这部分也需要调用api添加。
  2. 要实现set和get方法。

把相关api的调用封装成一个方法:

void test_class_addProperty(Class targetClass , const char *propertyName){
    // 添加属性
    objc_property_attribute_t type = { "T", [[NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([NSString class])] UTF8String] }; //type
    objc_property_attribute_t ownership1 = { "C", "" }; // C = copy
    objc_property_attribute_t ownership2 = { "N", "" }; //N = nonatomic
    objc_property_attribute_t ivar  = { "V", [NSString stringWithFormat:@"_%@",[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]].UTF8String };  //variable name
    objc_property_attribute_t attrs[] = {type, ownership1, ownership2, ivar};

    class_addProperty(targetClass, propertyName, attrs, 4);
    
    // 添加setter  +  getter 方法
    class_addMethod(targetClass, @selector(setInfo:), (IMP)testSetter, "v@:@");
    class_addMethod(targetClass, @selector(info), (IMP)testInfo, "@@:");
}

添加属性的时候ownership的两个变量中分别设置了‘C’和‘N’,分别代表的是‘copy’和‘nonatomic’,其他的配置如图:


添加方法的时候,例如添加setter方法class_addMethod(targetClass, @selector(setInfo:), (IMP)testSetter, "v@:@");

  1. 参数1:目标类
  2. 参数2:sel
  3. 参数3:imp
  4. 参数4:方法签名,v代表返回值为void类型,@代表对象,冒号(:)是sel。更多参数参考下图:


demo地址:动态添加类Demo

相关文章

  • 自己实现OC的KVO

    Runtime系列文章在这:Runtime介绍---术语介绍Runtime应用--动态添加方法Runtime应用-...

  • runtime应用--添加动态类

    创建类 因为要使用runtime的api,所以要导入头文件#import 创建类代...

  • Runtime 在实际开发中的应用

    runtime再实际开发中主要应用 1.动态添加一个类 2.通过runtime获取一个类的所有属性,我们可以做些什...

  • runtime相关

    修改系统方法 动态添加方法 动态给系统类添加属性(给分类添加属性) runtime+kvc 转换模型

  • ios runtime

    什么是runtime runtime运用 在程序运行过程中,动态的创建类,动态添加、修改这个类的属性和方法 遍历一...

  • 动态添加属性

    动态添加属性:什么时候需要动态添加属性? 开发场景:给系统的类添加属性的时候,可以使用runtime动态添加属性方...

  • Runtime 04 - 应用(动态创建类、交换方法)

    Runtime 04 - 应用(动态创建类、交换方法) 动态创建类 需要创建的类结构如下 动态创建类的示例 先定义...

  • runtime的理解(二)

    主要内容 利用 runtime 交换方法 利用 runtime 动态添加方法 利用 runtime 动态添加属性 ...

  • iOS开发经验(14)-runtime

    目录 回顾类&对象&方法 OC的动态特性 Runtime详解 应用场景 Runtime缺点及Runtime常用函数...

  • Objective-C关联对象的实现

    目的 在 NSObject 类中,添加 name 属性。 方案 利用 runtime 的相关方法: 动态添加属性 ...

网友评论

      本文标题:runtime应用--添加动态类

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