Как получить имя функции метода в Objective-C? - PullRequest
0 голосов
/ 28 февраля 2011

Насколько я знаю, метод скомпилирован в функцию, подобную этой:

+(NSArray *)arrayWithObject:(id)object;
// becomes
NSArray *_c_NSArray_arrayWithObject_(id object);

Можно ли получить имя функции селектора, чтобы я мог передать метод в качестве аргумента функции C или это невозможно?

Ответы [ 2 ]

6 голосов
/ 28 февраля 2011

Не совсем - они выглядят так:

id method(id, SEL, ...); 

Таким образом, метод Objective-C (будь то метод класса или экземпляра) предполагает получение экземпляра класса, к которому он вызывается (который будет метаклассом в случае метода класса), и селектора, который его вызвал .

Этот тип определяется как 'IMP' в objc.h:

typedef id          (*IMP)(id, SEL, ...); 

Вы можете получить указатель IMP либо с помощью функции C class_getMethodImplementation , либо с помощью + instanceMethodForSelector: (или -methodForSelector: , если хотите чтобы позволить конкретному экземпляру, возможно, перестроить его методы во время выполнения) метод на все, что происходит от NSObject.

Так, например,

#import <objc/objc.h>

id someObject = ...something...;
IMP functionPointerToMethod = [someObject methodForSelector:@selector(method)];

functionPointerToMethod(someObject, @selector(method));

Или:

IMP functionPointerToMethod = [someObject methodForSelector:@selector(method:)];
functionPointerToMethod(someObject, @selector(method:), argument);

Или даже:

IMP functionPointerToMethod = class_getMethodImplementation([someObject class],
                                                            @selector(method:));

functionPointerToMethod(someObject, @selector(method:), argument);

Конечно, во всем этом вы удаляете обычную динамическую диспетчеризацию Objective-C из цикла. Поэтому, если вы впоследствии добавите или перегруппируете методы в классе, указатель на вашу функцию C устареет.

Методы класса доступны практически теми же средствами, но через метакласс, например,

// to do the same as [NSString alloc], not that you ever would...
IMP functionPointerToAlloc = [[NSString class] methodForSelector:@selector(alloc)];
functionPointerToMethod([NSString class], @selector(alloc));
2 голосов
/ 28 февраля 2011

Вы можете использовать что-то, известное как селектор, чтобы передать имя метода.Селекторы - это, в основном, имя метода, который можно использовать для вызова этого метода.Например,

SEL aSelector; 
aSelector = @selector(aMethod:);

Это будет означать, что вы используете метод "aMethod:", и теперь вы можете передать этот селектор (тип SEL) в параметрах другой функции.Не уверен, что это то, что вы ищете, но надеюсь, что это поможет.

Вы также можете вызвать метод, сказав что-то вроде:

[anObject performSelector:aSelector];
...