我想以编程方式将代码与选择器关联起来。我不清楚在Objective C中如何做到这一点。在Ruby中,我可能会覆盖method_missing
。在Common Lisp中,我可能会定义一个宏。在Objective C中,我可以通过@dynamic
属性获得部分方法,但我不清楚如何实现它们。
这是一个具体的例子:我想使用NSMutableDictionary
来持久存储我的对象的一部分。我的类有两个处理基本功能的方法,以及一堆动态属性(@property
中存在匹配@interface
):
@dynamic name;
@dynamic age;
@dynamic favoriteColor;
- (id)accessor:(NSString*)name {
return [[self dict] objectForKey:name];
}
- (void)mutator:(NSString*)name value:(id)value{
[[self dict] setObject:value forKey:name];
[[self dict] writeToFile:[self filename] atomically:YES];
}
现在我正在寻找一种方法来翻译像
这样的电话[myInstance setName:@"iter"];
到
[self mutator:@"name" value@"iter"];
我想知道在ObjC中是否有一种惯用的方式。
答案 0 :(得分:2)
在Objective-C中,这不是一个惯用的事情,并且肯定没有像Lisp宏那样可用。但是,NSObject
和运行时提供了三个可能的点来拦截和处理引用其他方法的消息。按照运行时使用的顺序:resolveInstanceMethod:
,forwardInvocation:
和doesNotRespondToSelector:
。每个文档都说明了它们的用法并给出了一些例子。
第一个要求你实际写出和add一个方法,这似乎不会达到你想要的动态状态。默认情况下,last引发异常并且不提供任何返回值。几乎可以肯定,forwardInvocation
是您想要研究的内容。它允许您的对象请求另一个对象来处理方法调用,包括传递的参数;应该可以让你的对象以至少让你接近你想要的方式处理调用本身。
此外,运行时编程指南的"Message Forwarding"章节提供了一些与您的要求类似的任务示例。
答案 1 :(得分:1)
如果某个对象没有您调用的方法,则可以覆盖forwardInvocation
以将方法调用委托给另一个对象。
答案 2 :(得分:0)
您可以使用Objective-C runtime functions和resolveInstanceMethod:
。 resolveInstanceMethod:
文档中有一个简短示例。