如何在运行时向对象添加属性? [英] How can I add properties to an object at runtime?
问题描述
是否可以在运行时向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 $ c>之外,
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屋!