Динамически привязывать метод к селектору во время выполнения - PullRequest
2 голосов
/ 18 июля 2011

Я хочу программно связать код с селекторами.Мне не ясно, как это сделать в Objective C. В Ruby я могу переопределить method_missing.В Common Lisp я мог бы определить макрос.В Objective C я могу получить часть пути с @dynamic свойствами, но мне неясно, как на самом деле их реализовать.

Вот конкретный пример: я хочу использовать NSMutableDictionary дляпостоянно храните части моего объекта.В моем классе есть два метода, которые обрабатывают основную функциональность, и набор динамических свойств (соответствующие @property существуют в @interface):

@dynamic name;
@dynamic age;
@dynamic favoriteColor;
- (id)accessor:(NSString*)name {
    return [[self dict] objectForKey:name];
}
- (void)mutator:(NSString*)name value:(id)value{
    [[self dict] setObject:value forKey:name];
    [[self dict] writeToFile:[self filename] atomically:YES];
}

Теперь я ищу способ перевести вызовкак

[myInstance setName:@"iter"];

в

[self mutator:@"name" value@"iter"];

Интересно, есть ли идиоматический способ сделать это в ObjC.

Ответы [ 3 ]

2 голосов
/ 18 июля 2011

Это не совсем идиоматическая вещь, которую нужно делать в Objective-C, и, конечно, нет ничего похожего на макрос Lisp. Однако NSObject и среда выполнения обеспечивают три возможных момента для перехвата и обработки сообщений, относящихся к методам, которые в противном случае не существуют. В порядке их использования средой выполнения: resolveInstanceMethod:, forwardInvocation: и doesNotRespondToSelector:. Документация для каждого из них объясняет их использование и дает несколько примеров.

Первый требует, чтобы вы действительно выписали и добавили метод к классу, который, похоже, не достигнет желаемого вами динамического состояния. Последнее по умолчанию вызывает исключение и не предусматривает никакого возвращаемого значения. Почти наверняка, forwardInvocation это то, что вы хотите посмотреть. Это позволяет вашему объекту запрашивать другой объект для обработки вызова метода, включая переданные аргументы; у вас должна быть возможность заставить свой объект обрабатывать сам вызов таким образом, чтобы, по крайней мере, приблизить вас к тому, к чему вы стремитесь.

Также в главе «Пересылка сообщений» *1019* Руководства по программированию во время выполнения приведены некоторые примеры задач, аналогичных вашим требованиям.

1 голос
/ 18 июля 2011

Если объект не имеет вызванного вами метода, вы можете переопределить forwardInvocation, чтобы делегировать вызов метода другому объекту.

0 голосов
/ 18 июля 2011

Вы можете использовать Функции времени выполнения Objective C вместе с resolveInstanceMethod:. Вот краткий пример в resolveInstanceMethod: документах.

...