有没有办法做一些类似于KVC但是使用消息名称作为密钥本身?例如,对象是否有一种方法可以响应所有消息而不是valueForKey:
?
例如,假设您有一个XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ...>
<employees>
<employee>
<name>Bill</name>
<department>Accounting</department>
</employee>
<employee>
<name>John</name>
<department>Human Resources</department>
</employee>
</employees>
除了使用已经可用的NSXMLDocument和co。之外,还有办法实现某种抽象,所以你可以这样做:
MyXML *xmlDoc = [[MyXML alloc] initWithContentsOfFile:@"test.xml"];
NSLog (@"%@", [[[xmlDoc employees] first] department]);
[[[xmlDoc employees] first] setDepartment:@"Management"];
我选择XML只是作为一个例子,但我想知道这是否可行,以及它是否涉及过于接近Objective-C运行时或者是否受运行时本身支持,以及如何我会去实现这样的东西。这纯粹是出于实验目的,我理解可能会有很大的性能成本。
修改
如果可能的话,我想避免像Cocoa这样的现有框架,并使用基础Objective-C对象Object
。
答案 0 :(得分:3)
您需要实施forwardInvocation:
和methodSignatureForSelector:
来处理无法识别的邮件。 NSObject
引用中为described。
编辑:维基百科有example如何为Object完成转发,基本上是通过实施forward:
和performv:
。
答案 1 :(得分:1)
感谢codelogic,我发现你需要为GCC的Objective-C运行时做的所有事情是:
#import <obc/Object.h>
#import <stdio.h>
@interface RespondsToEverything : Object {}
@end
@implementation RespondsToEverything
- (retval_t) forward:(SEL) sel :(arglist_t) argFrame
{
fprintf (stderr, "Received: %s\n", get_sel_name (sel));
}
@end
int main (int argc, char *argv[])
{
id test = [RespondsToEverything new];
[test asdfasdfasdfasdf];
[test zxcvzxcvzxcvzxcv];
return 0;
}
输出结果为:
Received: asdfasdfasdfasdf
Received: zxcvzxcvzxcvzxcv
但是,当然,GCC抱怨它找不到asdfasdfasdfasdf
和zxcvzxcvzxcvzxcv
的方法签名。没什么大不了的,它仍然表明这个概念是可行的。在Apple的运行时中,您可以使用sel_getName(sel)
代替get_sel_name(sel)
。