Подтвердить что ты не робот

Динамически вызывать метод класса в 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 {
   // ???
}
4b9b3361

Ответ 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: метод, который делает именно это.