Динамически вызывать метод класса в Objective C
Предположим, что у меня есть Objective C interface SomeClass
, у которого есть метод класса someMethod
:
@interface SomeClass : NSObject {
}
+ (id)someMethod;
@end
В другом интерфейсе я хочу иметь вспомогательный метод, который динамически вызывает someMethod
в классе, подобном этому:
[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];
Какова должна быть реализация для invokeSelector
? Возможно ли вообще?
- (void)invokeSelector:(SEL)aSelector forClass:(Class)aClass {
// ???
}
Ответы
Ответ 1
Вместо:
[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];
вызов:
[[SomeClass class] performSelector:@selector(someMethod)];
Пример (с использованием GNUstep...)
файл A.h
#import <Foundation/Foundation.h>
@interface A : NSObject {}
- (NSString *)description;
+ (NSString *)action;
@end
файл A.m
#import <Foundation/Foundation.h>
#import "A.h"
@implementation A
- (NSString *)description
{
return [NSString stringWithString: @"A"];
}
+ (NSString *)action
{
return [NSString stringWithString:@"A::action"];
}
@end
Где-то еще:
A *a = [[A class] performSelector:@selector(action)];
NSLog(@"%@",a);
Вывод:
2009-11-22 23:32:41.974 abc[3200] A::action
Хорошее объяснение от http://www.cocoabuilder.com/archive/cocoa/197631-how-do-classes-respond-to-performselector.html:
"В Objective-C объект класса получает все методы экземпляра
root для своей иерархии. Это означает, что каждый объект класса
что нисходящий из NSObject получает все методы экземпляра NSObject -
включая performSelector:. "
Ответ 2
В Objective-C классы также являются объектами. Однако объекты класса обрабатываются по-разному, поскольку они могут вызывать методы экземпляра их корневого класса (NSObject
или NSProxy
в Cocoa).
Таким образом, можно использовать все методы экземпляра, определенные в NSObject
для объектов класса, а также правильный способ динамического вызова метода класса:
[aClass performSelector:@selector(aSelector)];
apple docs являются более конкретными.
Ответ 3
Вы не должны реализовывать это самостоятельно.
Протокол NSObject имеет performSelector:
метод, который делает именно это.
Ответ 4
Является ли этот встроенный метод тем, что вы хотите?
id objc_msgSend(id theReceiver, SEL theSelector, ...)
(См. справочные документы runtime для этой функции.)