不完全——它们看起来像:
id method(id, SEL, ...);
因此,Objective-C 方法(无论是类方法还是实例方法)都期望获取正在调用它的类的实例(在类方法的情况下将是元类)和触发它的选择器.
这个类型被objc.h定义为'IMP':
typedef id (*IMP)(id, SEL, ...);
您可以通过使用 C 函数 class_getMethodImplementation 或使用 +instanceMethodForSelector:(或 -methodForSelector:,如果您想允许可能在运行时重新排列其方法的特定实例)方法获取 IMP 指针在任何从 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));