美文网首页
动态添加属性

动态添加属性

作者: Dombo_Y | 来源:发表于2023-03-01 11:53 被阅读0次
   // 1: 动态创建类
        Class LGPerson = objc_allocateClassPair([NSObject class], "LGPerson", 0);
        // 2: 添加成员变量 1<<aligment
        // ivar - ro - ivarlist
        class_addIvar(LGPerson, "lgName", sizeof(NSString *), log2(sizeof(NSString *)), "@");
        // 3: 注册到内存
        objc_registerClassPair(LGPerson);
        
        // cls->ISA()->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
        // cls->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
       
        // 3.1 添加property - rw
        lg_class_addProperty(LGPerson, "subject");
        lg_printerProperty([LGTeacher class]);
        lg_printerProperty(LGPerson);

        // 3.2 添加setter  +  getter 方法
        class_addMethod(LGPerson, @selector(setSubject:), (IMP)lgSetter, "v@:@");
        class_addMethod(LGPerson, @selector(subject), (IMP)lgName, "@@:");

        // 开始使用
        id person = [LGPerson alloc];
        [person setValue:@"KC" forKey:@"lgName"];
        NSLog(@"%@",[person valueForKey:@"lgName"]);
        
        id teacher = [LGTeacher alloc];
        [teacher setValue:@"iOS" forKey:@"subject"];
        NSLog(@"%@",[teacher valueForKey:@"subject"]);
        
        [person setValue:@"master" forKey:@"subject"];
        NSLog(@"%@",[person valueForKey:@"subject"]);

void lgSetter(NSString *value){
    printf("%s/n",__func__);
}

NSString *lgName(){
    printf("%s/n",__func__);
    return @"master NB";
}

void lg_class_addProperty(Class targetClass , const char *propertyName){
    
    objc_property_attribute_t type = { "T", [[NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([NSString class])] UTF8String] }; //type
    objc_property_attribute_t ownership0 = { "C", "" }; // C = copy
    objc_property_attribute_t ownership = { "N", "" }; //N = nonatomic
    objc_property_attribute_t backingivar  = { "V", [NSString stringWithFormat:@"_%@",[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]].UTF8String };  //variable name
    objc_property_attribute_t attrs[] = {type, ownership0, ownership,backingivar};

    class_addProperty(targetClass, propertyName, attrs, 4);

}

void lg_printerProperty(Class targetClass){
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(targetClass, &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
    }
}

// 相关api 的注释

/**
 * 创建类对
 *superClass: 父类,传Nil会创建一个新的根类
 *name: 类名
 *extraBytes: 0
 *return:返回新类,创建失败返回Nil,如果类名已经存在,则创建失败
  objc_allocateClassPair(<#Class  _Nullable __unsafe_unretained superclass#>, <#const char * _Nonnull name#>, <#size_t extraBytes#>)
 */


/**
 *添加成员变量
 *
 *cls 往哪个类添加
 *name 添加的名字
 *size 大小
 *alignment 对齐处理方式
 *types 签名
 *
 *这个函数只能在objc_allocateClassPair和objc_registerClassPair之前调用。不支持向现有类添加一个实例变量。
 *这个类不能是元类。不支持在元类中添加一个实例变量。
 *实例变量的最小对齐为1 << align。实例变量的最小对齐依赖于ivar的类型和机器架构。对于任何指针类型的变量,请通过log2(sizeof(pointer_type))。
  class_addIvar(<#Class  _Nullable __unsafe_unretained cls#>, <#const char * _Nonnull name#>, <#size_t size#>, <#uint8_t alignment#>, <#const char * _Nullable types#>)
 */

/**
 *往内存注册类
 *
 * cls 要注册的类
 *
 * objc_registerClassPair(<#Class  _Nonnull __unsafe_unretained cls#>)
 */


/**
 *往类里面添加方法
 *
 *cls 要添加方法的类
 *sel 方法编号
 *imp 函数实现指针
 *types 签名
 *
 *class_addMethod(<#Class  _Nullable __unsafe_unretained cls#>, <#SEL  _Nonnull name#>, <#IMP  _Nonnull imp#>, <#const char * _Nullable types#>)
 */



/**
 *往类里面添加属性
 *
 *cls 要添加属性的类
 *name 属性名字
 *attributes 属性的属性数组。
 *attriCount 属性中属性的数量。
 *
 *class_addProperty(<#Class  _Nullable __unsafe_unretained cls#>, <#const char * _Nonnull name#>, <#const objc_property_attribute_t * _Nullable attributes#>, <#unsigned int attributeCount#>)
 */

相关文章

网友评论

      本文标题:动态添加属性

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