是否可以在运行时将属性添加到Objective C对象?如何在运行时将属性添加到对象?
39
A
回答
60
有可能通过class_addProperty()
正规的属性添加到一个类:
BOOL class_addProperty(Class cls,
const char *name,
const objc_property_attribute_t *attributes,
unsigned int attributeCount)
前两个参数是不言自明的。第三个参数是一组属性属性,每个属性属性都是一个名称 - 值对,它跟在Objective-C type encodings后面declared properties。请注意,该文档仍然提到了用于编码属性属性的逗号分隔字符串。逗号分隔的字符串中的每个段由一个objc_property_attribute_t
实例表示。此外,objc_property_attribute_t
接受除id
的通用@
类型编码之外的类别名称。
这里有一个程序的第一稿动态添加一个名为name
属性已经有一个名为_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, "[email protected]:@");
id o = [SomeClass new];
NSLog(@"%@", [o name]);
[o setName:@"Jobs"];
NSLog(@"%@", [o name]);
}
}
它(修剪)输出:
Steve
Jobs
getter和setter方法应该更仔细地编写,但这应该足以作为如何在运行时动态添加正式属性的示例。
4
@properties - no(即使用点语法等)。但是您可以使用关联对象添加存储:How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?。
8
如果你看一看NSKeyValueCoding
协议,记录here,你可以看到,有一个名为消息:
- (id)valueForUndefinedKey:(NSString *)key
您应该重写该方法以提供自定义的结果为指定未定义的属性。当然这假定你的班级使用相应的协议。
这种方法通常用于向类(例如,不存在的选择器)提供未知行为。
相关问题
- 1. 如何在运行时在expando上添加对象属性?
- 2. 如何将属性添加到对象?
- 3. 如何在Objective-C的运行时将动态属性添加到对象?
- 4. 如何使用C++在运行时将新属性添加到对象中?
- 5. C#:如何在运行时向对象添加属性?
- 6. 在运行时添加属性到Javascript对象
- 7. 如何将运行时参数命名的属性添加到动作对象?
- 8. 如何在C#中将运行时属性添加到类中?
- 9. 如何在运行时将属性添加到方法?
- 10. 当属性不为空时将属性添加到对象
- 11. 如何添加属性到对象
- 12. 使用propertyBuilder在运行时向现有对象添加属性
- 13. 的Javascript添加事件,在运行时对象属性
- 14. 将新属性添加到.Net对象
- 15. 将属性添加到KineticJS对象
- 16. 将属性添加到对象
- 17. 将属性添加到python对象
- 18. 将属性添加到对象
- 19. 将新属性添加到对象
- 20. 如何在运行时向属性添加属性
- 21. 如何在运行时在javascript中添加/删除属性对象
- 22. 将运行时(动态)的EditorAttribute添加到对象的特殊属性
- 23. 如何在迭代对象类型时添加到ICollection属性?
- 24. 检测何时将新属性添加到Javascript对象?
- 25. 在运行时将对象添加到ListView行
- 26. 在运行时将项添加到arrayList属性
- 27. 在运行时将属性添加到复选框列表
- 28. 在运行时将属性添加到列表<T>
- 29. 在运行时向对象添加属性并保存到数据库
- 30. 如何将多个对象添加到Groovy中的对象属性? ---在Bootstrap.groovy
如果它符合KVC协议 - 这是可能的 – Nekto
你是什么意思的属性? Objective-C声明的属性? – 2011-10-19 22:30:27
我的意思是@property – cfischer