据我所知,一个方法被编译成这样的函数:
+(NSArray *)arrayWithObject:(id)object;
// becomes
NSArray *_c_NSArray_arrayWithObject_(id object);
是否可以获取选择器函数的名称,以便将该方法作为参数传递给C函数,或者这是不可能的?
答案 0 :(得分:6)
不完全 - 他们看起来像:
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));
答案 1 :(得分:2)
您可以使用称为选择器的内容来传递方法的名称。选择器基本上是方法的名称,可用于调用该方法。例如
SEL aSelector;
aSelector = @selector(aMethod:);
这意味着您采用方法“aMethod:”,现在您可以在另一个函数的参数中传递该选择器(类型SEL)。不确定这是否是您正在寻找的,但希望它有所帮助。
您也可以通过以下方式调用该方法:
[anObject performSelector:aSelector];