3 回答

TA貢獻1909條經驗 獲得超7個贊
可以通過class_addProperty()以下方式向類添加形式屬性:
BOOL class_addProperty(Class cls,
const char *name,
const objc_property_attribute_t *attributes,
unsigned int attributeCount)
前兩個參數是不言自明的。第三個參數是屬性的屬性的陣列,并且每個屬性特性是一個名稱-值對,其遵循的Objective-C 型編碼對聲明的屬性。請注意,文檔中仍然提到了逗號分隔的字符串,用于屬性屬性的編碼。逗號分隔的字符串中的每個段均由一個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, "v@:@");
id o = [SomeClass new];
NSLog(@"%@", [o name]);
[o setName:@"Jobs"];
NSLog(@"%@", [o name]);
}
}
其(修剪后的)輸出:
Steve
Jobs
應該更加仔細地編寫getter和setter方法,但這足以作為如何在運行時動態添加形式屬性的示例。

TA貢獻1858條經驗 獲得超8個贊
如果您查看此處NSKeyValueCoding記錄的協議,則可以看到一條消息:
- (id)valueForUndefinedKey:(NSString *)key
您應該重寫該方法以為指定的undefined屬性提供自定義結果。當然,這假定您的類使用相應的協議。
這種方法通常用于向類提供未知的行為(例如,不存在的選擇器)。

TA貢獻1853條經驗 獲得超9個贊
否(即,使用點語法等)。但是您可以使用關聯對象來添加存儲:如何在對象內部使用objc_setAssociatedObject / objc_getAssociatedObject?。
- 3 回答
- 0 關注
- 536 瀏覽
添加回答
舉報