将方法的所有参数传递给NSLog

时间:2021-11-28 23:18:01

I print out something to the console using NSLog(). Is there a way to pass all the current method's arguments to NSLog(), or any other function or method, without looking at each of them explicitly?

我使用NSLog()将一些东西打印到控制台。是否有一种方法可以将当前方法的所有参数传递给NSLog()或任何其他函数或方法,而不需要显式地查看它们中的每一个?

For example, I already have a macro that prints useful information to the console when I just put LOGME in my code. The macro will create a call to a singleton class's logging-method and pass several useful things like _cmd and other stuff.

例如,我已经有一个宏,当我在代码中输入LOGME时,它将有用的信息打印到控制台。宏将创建对单例类的logging方法的调用,并传递一些有用的东西,比如_cmd和其他东西。

I would also like to catch all the arguments of that method and pass them on for printing them out automatically. Is that possible?

我还希望捕获该方法的所有参数,并将它们传递给它们,以便自动打印出来。这有可能吗?

2 个解决方案

#1


3  

Use gdb. You can set a break point that logs the arguments to the method and continues.

使用gdb。您可以设置一个断点,将参数记录到该方法并继续。

If you insist on doing it the hard way... It's certainly not simple, but you could use the stack structure on a given architecture/ABI and make use of the Objective-C runtime to figure out how many arguments and of what size to look for. From here on out, I'm in unchartered territory; I've never done this nor would I ever bother. So YMMV...

如果你坚持用艰难的方式去做……这当然不简单,但是您可以在给定的体系结构/ABI上使用堆栈结构,并使用Objective-C运行时来计算要查找的参数和大小。从现在开始,我进入了未知的领域;我从来没有做过这件事,我也不会去做。所以YMMV…

Within your method, you can get the Method struct, then the number of arguments, then each argument type and the its size. You could then walk the stack from the address of the self parameter (i.e. &self), assuming you knew what you were doing...

在您的方法中,您可以获得方法结构,然后是参数的数量,然后是每个参数类型及其大小。然后你可以从self参数的地址(也就是self)中走出来,假设你知道自己在做什么……

Method method = class_getInstanceMethod([self class], _cmd);
unsigned nargs = method_getNumberOfArguments(method);
void *start = &self;
for(unsigned i = 0; i<nargs; i++) {
  char *argtype = method_copyArgumentType(method, i);
  //find arg size from argtype
  // walk stack given arg zie
  free(argtype);
}

Along the way you'd have to convert from the argtype string (using the Objective-C type encodings) to the size of each argument on the stack.

在此过程中,您必须将argtype字符串(使用Objective-C类型编码)转换为堆栈上每个参数的大小。

Of course then you'd have to derive the format string for each type, and call NSLogv with an appropriate variable argument array containing the arguments, copied from their location on the stack. Probably a lot more work than its worth. Use the debugger.

当然,您必须为每种类型派生格式字符串,并使用适当的变量参数数组调用NSLogv,其中包含参数,从堆栈上的位置复制。可能比它的价值多得多。使用调试器。

#2


3  

There’s no way to address all arguments in the preprocessor or Objective-C.

没有办法处理预处理器或Objective-C中的所有参数。

The only way I’m aware of is by use of the debugger. You can add a breakpoint action in Xcode to do this easily. Right click in the leftmost column of a code window, select "Built-in breakpoints" -> "Log breakpoint and arguments and auto-continue".

我知道的唯一方法是使用调试器。您可以在Xcode中添加一个断点操作来轻松完成这一操作。在代码窗口最左边的列中右键单击,选择“内置断点”—>“日志断点和参数,并自动继续”。

#1


3  

Use gdb. You can set a break point that logs the arguments to the method and continues.

使用gdb。您可以设置一个断点,将参数记录到该方法并继续。

If you insist on doing it the hard way... It's certainly not simple, but you could use the stack structure on a given architecture/ABI and make use of the Objective-C runtime to figure out how many arguments and of what size to look for. From here on out, I'm in unchartered territory; I've never done this nor would I ever bother. So YMMV...

如果你坚持用艰难的方式去做……这当然不简单,但是您可以在给定的体系结构/ABI上使用堆栈结构,并使用Objective-C运行时来计算要查找的参数和大小。从现在开始,我进入了未知的领域;我从来没有做过这件事,我也不会去做。所以YMMV…

Within your method, you can get the Method struct, then the number of arguments, then each argument type and the its size. You could then walk the stack from the address of the self parameter (i.e. &self), assuming you knew what you were doing...

在您的方法中,您可以获得方法结构,然后是参数的数量,然后是每个参数类型及其大小。然后你可以从self参数的地址(也就是self)中走出来,假设你知道自己在做什么……

Method method = class_getInstanceMethod([self class], _cmd);
unsigned nargs = method_getNumberOfArguments(method);
void *start = &self;
for(unsigned i = 0; i<nargs; i++) {
  char *argtype = method_copyArgumentType(method, i);
  //find arg size from argtype
  // walk stack given arg zie
  free(argtype);
}

Along the way you'd have to convert from the argtype string (using the Objective-C type encodings) to the size of each argument on the stack.

在此过程中,您必须将argtype字符串(使用Objective-C类型编码)转换为堆栈上每个参数的大小。

Of course then you'd have to derive the format string for each type, and call NSLogv with an appropriate variable argument array containing the arguments, copied from their location on the stack. Probably a lot more work than its worth. Use the debugger.

当然,您必须为每种类型派生格式字符串,并使用适当的变量参数数组调用NSLogv,其中包含参数,从堆栈上的位置复制。可能比它的价值多得多。使用调试器。

#2


3  

There’s no way to address all arguments in the preprocessor or Objective-C.

没有办法处理预处理器或Objective-C中的所有参数。

The only way I’m aware of is by use of the debugger. You can add a breakpoint action in Xcode to do this easily. Right click in the leftmost column of a code window, select "Built-in breakpoints" -> "Log breakpoint and arguments and auto-continue".

我知道的唯一方法是使用调试器。您可以在Xcode中添加一个断点操作来轻松完成这一操作。在代码窗口最左边的列中右键单击,选择“内置断点”—>“日志断点和参数,并自动继续”。