是的,你可以做到這一點,但這是非常困難的。
訣竅是認識到方法實際上只是一個函數,並且即使未聲明方法/函數在簽名中採用...
,也可以從參數創建va_list
。
的僞代碼會是這樣大致是這樣的:
va_list args;
// start your argument list after the "_cmd" argument
va_start(args, _cmd);
// get the Method for this (instance) method
Method thisMethod = class_getInstanceMethod([self class], _cmd);
// get the type encoding string for this method
const char *methodType = method_getTypeEncoding(thisMethod);
// use the type encoding string to make an NSMethodSignature
NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:methodType];
// iterate through all the arguments, skipping 0 (self) and 1 (_cmd)
for (NSUInteger i = 2; i < [signature numberOfArguments]; ++i) {
// get the type of the argument
const char *type = [signature getArgumentTypeAtIndex:i];
// if this argument type is the same as an object, pull out an object
if (strcmp(@encode(id), type) == 0) {
id nextArg = va_arg(args, id);
NSLog(@"object argument: %@", nextArg);
// if this argument type is the same as a float, pull out a float
} else if (strcmp(@encode(float), type) == 0) {
float nextArg = va_arg(args, float);
NSLog(@"float argument: %f", nextArg);
} ...
// repeat as necessary for all the types you care to log
}
// cleanup
va_end(args);
幸運,其他人都希望這樣的事情之前已經想出了做它幾乎同樣的機制。下面是將NSLog
任意表達的東西的示例:
http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/
也許溶液可以使用['NSMethodSignature']來編造了(http://developer.apple.com/library/ios/#documentation /Cocoa/Reference/Foundation/Classes/NSMethodSignature_Class/Reference/Reference.html%23//apple_ref/doc/c_ref/NSMethodSignature),['NSInvocation'](http://developer.apple.com/library/ios/#文檔/可可/參考/基礎/類/ NSInvocation_Class/Reference/Reference.html)和朋友? –