How to get the function name of a method in Objective-C?
For as far as I know, a method is compiled into a function like this:
+(NSArray *)arrayWithObject:(id)object;
// becomes
NSArray *_c_NSArray_arrayWithObject_(id object);
Is it possible to get the name of the fu开发者_开发问答nction of a selector so I can pass the method as an argument to a C function, or is this not possible?
Not quite — they look like:
id method(id, SEL, ...);
So an Objective-C method (whether a class or instance method) expects to take the instance of the class it is being called on (which will be the metaclass in the case of a class method) and the selector that triggered it.
This type is defined as 'IMP' by objc.h:
typedef id (*IMP)(id, SEL, ...);
You can get an IMP pointer either by using the C function class_getMethodImplementation or by using the +instanceMethodForSelector: (or -methodForSelector:, if you want to allow for a particular instance possibly having had its methods rearranged at runtime) method on anything that descends from NSObject.
So, e.g.
#import <objc/objc.h>
id someObject = ...something...;
IMP functionPointerToMethod = [someObject methodForSelector:@selector(method)];
functionPointerToMethod(someObject, @selector(method));
Or:
IMP functionPointerToMethod = [someObject methodForSelector:@selector(method:)];
functionPointerToMethod(someObject, @selector(method:), argument);
Or even:
IMP functionPointerToMethod = class_getMethodImplementation([someObject class],
@selector(method:));
functionPointerToMethod(someObject, @selector(method:), argument);
Of course, in all this what you're doing is removing Objective-C's normal dynamic dispatch from the loop. So if you subsequently add or rearrange methods on a class then your C function pointer will become out of date.
Class methods are accessible by much the same means, but via the metaclass, e.g.
// to do the same as [NSString alloc], not that you ever would...
IMP functionPointerToAlloc = [[NSString class] methodForSelector:@selector(alloc)];
functionPointerToMethod([NSString class], @selector(alloc));
You can use something known as a selector to pass the name of a method. Selectors are basically the name of the method, which can be used to call that method. For example
SEL aSelector;
aSelector = @selector(aMethod:);
That would mean you take the method "aMethod:" and now you can pass that selector (type SEL) in parameters of another function. Not sure if this is what you are looking for, but hope it helps.
You can also call the method by saying something like:
[anObject performSelector:aSelector];
精彩评论