如何在运行时向对象添加属性? [英] How can I add properties to an object at runtime?

查看:118
本文介绍了如何在运行时向对象添加属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在运行时向Objective C对象添加属性?

Is it possible to add properties to an Objective C object at runtime?

推荐答案

class via class_addProperty()

It’s possible to add formal properties to a class via class_addProperty():

BOOL class_addProperty(Class cls,
    const char *name,
    const objc_property_attribute_t *attributes,
    unsigned int attributeCount)


$ b b

前两个参数是不言自明的。第三个参数是属性属性数组,每个属性属性都是一个名称/值对,遵循Objective-C 类型编码 声明的属性。请注意,文档仍然提及属性属性编码的逗号分隔字符串。逗号分隔字符串中的每个段都由一个 objc_property_attribute_t 实例表示。此外,除了 @ 类型编码 id 之外, objc_property_attribute_t $ c>。

The first two parameters are self-explanatory. The third parameter is an array of property attributes, and each property attribute is a name-value pair which follow Objective-C type encodings for declared properties. Note that the documentation still mentions the comma-separated string for the encoding of property attributes. Each segment in the comma-separated string is represented by one objc_property_attribute_t instance. Furthermore, objc_property_attribute_t accepts class names besides the generic @ type encoding of id.

这是一个程序的第一个草稿,动态添加一个属性 name 已有一个名为 _privateName 的实例变量:

Here’s a first draft of a program that dynamically adds a property called name to a class that already has an instance variable called _privateName:

#include <objc/runtime.h>
#import <Foundation/Foundation.h>

@interface SomeClass : NSObject {
    NSString *_privateName;
}
@end

@implementation SomeClass
- (id)init {
    self = [super init];
    if (self) _privateName = @"Steve";
    return self;
}
@end

NSString *nameGetter(id self, SEL _cmd) {
    Ivar ivar = class_getInstanceVariable([SomeClass class], "_privateName");
    return object_getIvar(self, ivar);
}

void nameSetter(id self, SEL _cmd, NSString *newName) {
    Ivar ivar = class_getInstanceVariable([SomeClass class], "_privateName");
    id oldName = object_getIvar(self, ivar);
    if (oldName != newName) object_setIvar(self, ivar, [newName copy]);
}

int main(void) {
    @autoreleasepool {
        objc_property_attribute_t type = { "T", "@\"NSString\"" };
        objc_property_attribute_t ownership = { "C", "" }; // C = copy
        objc_property_attribute_t backingivar  = { "V", "_privateName" };
        objc_property_attribute_t attrs[] = { type, ownership, backingivar };
        class_addProperty([SomeClass class], "name", attrs, 3);
        class_addMethod([SomeClass class], @selector(name), (IMP)nameGetter, "@@:");
        class_addMethod([SomeClass class], @selector(setName:), (IMP)nameSetter, "v@:@");

        id o = [SomeClass new];
        NSLog(@"%@", [o name]);
        [o setName:@"Jobs"];
        NSLog(@"%@", [o name]);
    }
}

其(修剪)输出:

Steve
Jobs


$ b b

getter和setter方法应该更仔细地写,但是这应该足以作为如何在运行时动态添加形式属性的示例。

The getter and setter methods should be written more carefully but this should be enough as an example of how to dynamically add a formal property at runtime.

这篇关于如何在运行时向对象添加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆