2011-07-02 67 views
4

可能重複:
How to pass all arguments of a method into NSLog?目標C日誌方法調用

我可以設置一個宏printCommand登錄方法調用的接收器和選擇器,如下所示:

#define printMethodCall NSLog (@"%@ %@", self, NSStringFromSelector(_cmd)); 

問題 - 上面可以擴展記錄所有與方法調用傳遞的參數,howev呃少數或多少,無論什麼類型,他們可能是?

+0

也許溶液可以使用['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)和朋友? –

回答

1

是的,你可以做到這一點,但這是非常困難的。

訣竅是認識到方法實際上只是一個函數,並且即使未聲明方法/函數在簽名中採用...,也可以從參數創建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/