2009-02-27 104 views
1

有沒有類似於KVC的方法,但是使用消息名稱作爲密鑰本身?例如,而不是valueForKey:,是否有方法讓對象響應所有消息?Objective-C消息傳遞,巧妙地處理未知消息

例如,假設你有一個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與合作,纔會有實現某種抽象的一種方式,所以你可以這樣做:

MyXML *xmlDoc = [[MyXML alloc] initWithContentsOfFile:@"test.xml"]; 

NSLog (@"%@", [[[xmlDoc employees] first] department]); 

[[[xmlDoc employees] first] setDepartment:@"Management"]; 

我選擇XML只是一個例子,但我想知道這是否可能,以及它是否涉及太接近Objective-C運行時或它是否受運行時本身支持,以及我將如何去執行像thi這樣的事情秒。這純粹是爲了實驗目的,我瞭解可能會有顯着的性能成本。

編輯:
如果可能,我想避免現有框架,如可可和使用基Objective-C的對象Object

回答

3

您需要實施forwardInvocation:methodSignatureForSelector:來處理無法識別的消息。在NSObject參考文獻中是described

編輯:維基百科有一個example如何轉發可以完成對象,基本上通過執行forward:performv:

+0

感謝那些有用的信息,但這是特定於可可,我正在尋找一個整體Objective-C的使用。例如,在Linux或Windows或Mac中編譯直接的Objective-C。 – dreamlax 2009-02-27 00:28:50

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抱怨它無法找到asdfasdfasdfasdfzxcvzxcvzxcvzxcv的方法簽名。沒有什麼大不了的,它仍然表明這個概念是可行的。在Apple的運行時中,您可以使用sel_getName(sel)而不是get_sel_name(sel)