开发者

objective C log method call [duplicate]

开发者 https://www.devze.com 2023-03-17 00:47 出处:网络
This question already has answers here: Closed 11 ye开发者_运维百科ars ago. Possible Duplicate: How to pass all arguments of a method into NSLog?
This question already has answers here: Closed 11 ye开发者_运维百科ars ago.

Possible Duplicate:

How to pass all arguments of a method into NSLog?

I can setup a macro printCommand to log the receiver and selector of a method call as follows:

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

Question -- can the above be extended to log all arguments that were passed with the method call, however few or many, and whatever types, they may be?


Yes you can do this, but it's quite difficult.

The trick is to realize that a method is really just a function, and that you can create a va_list from the arguments, even if the method/function wasn't declared to take ... in the signature.

The pseudo code would be something roughly like this:

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);

Fortunately, other people have wanted this sort of thing before and have come up with pretty much this same mechanism for doing it. Here's an example of something that will NSLog an arbitrary expression:

http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/

0

精彩评论

暂无评论...
验证码 换一张
取 消