Обмен сообщениями в Objective-C, умное обращение с неизвестными сообщениями - PullRequest
1 голос
/ 27 февраля 2009

Есть ли способ сделать что-то похожее на 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 или поддерживается ли он самим временем выполнения, и как Я хотел бы реализовать что-то вроде этого. Это чисто для экспериментальных целей, и я понимаю, что, вероятно, будут существенные затраты производительности.

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

Ответы [ 2 ]

3 голосов
/ 27 февраля 2009

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

РЕДАКТИРОВАТЬ: В Википедии есть пример того, как можно выполнить переадресацию для объекта, в основном путем реализации forward: и performv:.

1 голос
/ 27 февраля 2009

Благодаря 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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...