假设(为了论证)我有一个包含 NSDictionary 的 View 类。我想要一大堆属性,所有这些属性都访问该字典的成员。
例如,我想要@property NSString* title
和@property NSString* author
。
对于这些属性中的每一个,实现都是相同的:对于 getter,调用 [dictionary objectForKey:propertyName];
,对于 setter,调用 setObject:forKey:。
编写所有这些方法将花费大量时间并使用大量复制和粘贴代码。有没有办法自动生成它们,就像 Core Data 对 NSManagedObject 子类的 @dynamic 属性所做的那样?需要明确的是,我只希望通过这种方式访问我在 header 中定义的属性,而不仅仅是任意键。
我遇到过 valueForUndefinedKey: 作为键值编码的一部分,它可以处理 getter,但我不完全确定这是否是最好的方法。
我需要这些是显式属性,以便我可以在 Interface Builder 中绑定(bind)到它们:我最终计划为此 View 编写一个 IB 调色板。
(顺便说一句,我知道我使用 NSDictionary 来存储这些的示例有点做作。我实际上是在编写 WebView 的子类,属性将引用 HTML 元素的 ID,但这对逻辑并不重要我的问题!)
最佳答案
在阅读了 objective-c 运行时文档后,我设法自己解决了这个问题。
我实现了这个类方法:
+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
NSString *method = NSStringFromSelector(aSEL);
if ([method hasPrefix:@"set"])
{
class_addMethod([self class], aSEL, (IMP) accessorSetter, "v@:@");
return YES;
}
else
{
class_addMethod([self class], aSEL, (IMP) accessorGetter, "@@:");
return YES;
}
return [super resolveInstanceMethod:aSEL];
}
后跟一对 C 函数:
NSString* accessorGetter(id self, SEL _cmd)
{
NSString *method = NSStringFromSelector(_cmd);
// Return the value of whatever key based on the method name
}
void accessorSetter(id self, SEL _cmd, NSString* newValue)
{
NSString *method = NSStringFromSelector(_cmd);
// remove set
NSString *anID = [[[method stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""] lowercaseString] stringByReplacingOccurrencesOfString:@":" withString:@""];
// Set value of the key anID to newValue
}
由于此代码尝试实现在类上调用但尚未实现的任何方法,因此如果有人尝试调用您所期望的内容,则会导致问题。我计划添加一些合理性检查,以确保名称符合我的预期。
关于objective-c - 在 Cocoa 中编写我自己的 @dynamic 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3560364/