У меня есть следующий код, в котором я получаю указатель на метод экземпляра:Как получить селектор метода класса?
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface TestClass : NSObject
@end
@implementation TestClass
- (void)someMethod { // This is instance method, it's okay
NSLog(@"Hello from some method!");
}
@end
int main(int argc, const char * argv[]) {
typedef void (*MethodWithoutParams)();
MethodWithoutParams someMethodImplementation =
class_getMethodImplementation([TestClass class], @selector(someMethod));
someMethodImplementation();
return 0;
}
Это работает очень хорошо. Но если я хотел бы получить указатель на метод класса, он не работает:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface TestClass : NSObject
@end
@implementation TestClass
+ (void)someMethod { // This is class method, it doesn't work
NSLog(@"Hello from some method!");
}
@end
int main(int argc, const char * argv[]) {
typedef void (*MethodWithoutParams)();
MethodWithoutParams someMethodImplementation =
class_getMethodImplementation([TestClass class], @selector(someMethod));
someMethodImplementation();
return 0;
}
Это не работает, потому что он не может искать реализацию метода.
Я уверен, что должен работать, потому что это работает, если я получаю осуществление таким образом:
MethodWithoutParams someMethodImplementation =
[TestClass methodForSelector:@selector(someMethod)];
Так что я смотрел в реализацию NSObject и увидеть следующий код:
+ (IMP)methodForSelector:(SEL)sel {
if (!sel) [self doesNotRecognizeSelector:sel];
return object_getMethodImplementation((id)self, sel);
}
- (IMP)methodForSelector:(SEL)sel {
if (!sel) [self doesNotRecognizeSelector:sel];
return object_getMethodImplementation(self, sel);
}
object_getMethodImplementation()
Также функция has следующая реализация:
IMP object_getMethodImplementation(id obj, SEL name)
{
Class cls = (obj ? obj->getIsa() : nil);
return class_getMethodImplementation(cls, name);
}
Таким образом, реализация одинакова для поиска метода класса и поиска метода экземпляра.
Но это не сработает, и я понятия не имею, почему. Я предполагаю, что любой тип методов (как класса, так и экземпляра) будет размещен в таблице рассылки, и я могу получить указатель на любой из этих методов. Но, как вы видите, я не могу этого сделать.
Зачем вам это нужно? – Wain
@Wain Я просто хочу знать, как работает Objective-C Runtime. К сожалению, официальная документация не описывает этот вопрос настолько глубоко. –
Это не одна и та же реализация. 'self' в методе экземпляра и' self' в методе класса разные. Таким образом, он вызывает 'object_getMethodImplementation' с разными' self '. – mostruash