1

有没有办法做类似于 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 Object

4

2 回答 2

3

您需要实现forwardInvocation:methodSignatureForSelector:处理无法识别的消息。它在参考文献中有描述。NSObject

编辑:维基百科有一个如何为对象完成转发的例子forward:,基本上是通过实现and performv:

于 2009-02-27T00:22:22.097 回答
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).

于 2009-02-27T01:39:12.430 回答