2009-02-27 3 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 и сотрудничества, будет ли способ реализации какой-то абстракции, так что вы можете сделать:

В качестве примера я выбрал XML, но хочу знать, возможно ли это вообще, и включает ли он слишком близкое к времени выполнения Objective-C или поддерживается ли оно самой средой выполнения, и как я буду реализовывать что-то вроде thi s. Это исключительно для экспериментальных целей, и я понимаю, что, вероятно, будут значительные затраты на производительность.

EDIT:
Если возможно, я хотел бы избежать существующих механизмов, таких как какао и использовать базовый объект Objective-C Object.

ответ

3

Для обработки нераспознанных сообщений вам необходимо реализовать forwardInvocation: и methodSignatureForSelector:. Это described в справочнике NSObject.

EDIT: В Википедии есть example того, как экспедирование может быть выполнено для объекта, в основном путем реализации forward: и performv:.

+0

Спасибо за эту полезную информацию, но это касается Какао, я ищу общую цель Objective-C. Например, скомпилируйте просто Objective-C в Linux или Windows или Mac. – dreamlax

1

Благодаря codelogic, я узнал все, что вам нужно сделать для Objective-C среды выполнения GCC является:

#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).

Смежные вопросы