假设(为了参数)我有一个包含NSDictionary的视图类.我想要一大堆属性,所有属性都可以访问该字典的成员.
例如,我想@property NSString* title
和@property NSString* author
.
对于这些属性中的每一个,实现都是相同的:对于getter,call [dictionary objectForKey:propertyName];
和setter,对setObject:forKey:执行相同的操作.
这需要花费大量时间并使用大量的复制粘贴代码来编写所有这些方法.有没有办法自动生成它们,就像Core Data使用NSManagedObject子类的@dynamic属性一样?为了清楚起见,我只希望这种方法可以访问我在标题中定义的属性,而不仅仅是任意键.
我遇到过valueForUndefinedKey:作为键值编码的一部分,它可以处理getter,但我不完全确定这是否是最好的方法.
我需要这些是显式属性,所以我可以在Interface Builder中绑定它们:我最终计划为这个视图编写一个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 }
由于此代码尝试实现在类上调用但尚未实现的任何方法,因此如果有人尝试调用您需要注意的内容,则会导致问题.我计划添加一些健全性检查,以确保名称符合我的期望.