在Objective-C中使用宏登录函数名和行号 [英] Using macro in Objective-C to log function name and line number

查看:140
本文介绍了在Objective-C中使用宏登录函数名和行号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下简化code例如:

I have the following simplified code example:

// in .h file
// define a macro for partial method
#define debugWithMsg context:(CFStringRef)__FUNCTION__ lineNumber:__LINE__ debug:

@interface MyLogger : NSObject {
  ...
}

- (void) context:(CFStringRef)function 
      lineNumber:(int)line 
           debug:(NSString*)messageFormat, ...;
@end

我在使用其他类此方法来打印调试消息于X code控制台。这里是测试我的调试方法(在MyViewController类与表视图)的例子:

I use this method in other classes to print debug messages to XCode console. Here is an example I test my debug method(in MyViewController class with a table view):

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
  ...
  // myLogger is an instance of MyLogger.
  [myLogger debugWithMsg@"something for %@", @"testing!"];
  ...
}
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  ...
  [myLogger debugWithMsg@"something for %@", @"another testing!"];
  ...
}

在上面的例子中工作得很好;但是,对我来说,它看起来并不像一个标准的C / C ++或ObjC语法。我需要使用这个宏的原因是,我想前两个参数传递的常数的方法。其实,这两个参数也是宏:__FUNCTION__是一个C ++宏,__LINE__是C标准的宏。这两个特定的宏将被动态地映射到功能的串和其中该方法被称为一个行号。例如上面的调试方法调用打印在X $ C $。c控制台这样的信息:

The above example works well; however, for me, it does not look like a standard C/C++ or ObjC syntax. The reason I need to use this macro is that I would like to pass the first two arguments as "constants" to the method. Actually, those two arguments are also macros: __FUNCTION__ being a C++ macro, and __LINE__ being a C standard macro. Those two special macros would be dynamically mapped to a string of the function and a line number where the method is called. For example the above debug method call prints a msg in XCode console like this:

[timestamp] -[MyViewController tableView:numberOfRowsInSection:] line:107 - something for testing!
...
[timestamp] -[MyViewController tableView:cellForRowAtIndexPath:] line:124 - something for another testing!

该MyLogger类主要是针对我的内部使用。是否有其他更好的做法,得到同样的结果?或者是有这个实现什么问题?

The MyLogger class is mainly for my internal use. Is there any other better practice to get the same result? Or is there any problem with this implementation?

我想定义以同样的方式作为的NSLog(FMT,...),这是一个宏,以及我的宏:

I am thinking to define my macro in the same way as NSLog(fmt, ...), which is a macro as well:

MyDebugLog(instance, fmt, ....)

其中,instance是MyLogger的一个实例,FMT,...是格式字符串和VAR名单。这是宏观的对我的审判定义:

where instance is an instance of MyLogger, and fmt, ... are format string and var list. This is my trial definition of the macro:

#define MyDebugLog(logger, fmt, ...) \
  [logger, context:(CFStringRef)__FUNCTION__ lineNumber:__LINE__ \
   debug:fmt, ## _VA_ARGS__]

我得到编译错误说语境未申报在我的code,其中使用了宏:

I got compiling error saying "'context' undeclared" in my code where the macro is used:

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
  ...
  // myLogger is an instance of MyLogger.
  MyDebugLog(myLogger, @"something for %@", @"testing!"); // compiling error!
  ...
}

不知道什么是错在我的定义。有什么建议么?

Not sure what's wrong in my definition. Any suggestions?

推荐答案

这是我使用。

的#define SFLog(消息,...)的NSLog((@SFLOG:%S [%d行]消息),__ preTTY_FUNCTION__,__LINE__,## __VA_ARGS __)

您使用它酷似 SFLog(@有些VAR%F,myFloat); ,除了它prepends了SFLog(我也用'SFError ')和 __ preTTY_FUNCTION __ 宏。

You use it exactly like SFLog(@"Some var %f", myFloat); except it prepends the 'SFLog' (I also use 'SFError') and the __PRETTY_FUNCTION__ macros.

我发现SO帖子里我得到了这一点。 这是在这里。

I found the SO post where I got this. It's over here.

莱弗勒低于宏可以在不#定义指出#。在 ## 是一个纯粹的海湾合作​​委员会的东西,不符合C99标准。 ## 也与LLVM / Clang的1.5(X code 3.2.4),以及用于-std = C99和-std = gnu99编译器设置。只要明白我们是宏观一些限制,如果如预期它不工作。

Commenter Jonathan Leffler points out below that the macro can be defined without the ##. The ## is purely a GCC thing, and doesn't conform to C99 standard. ## also works with LLVM/Clang 1.5 (XCode 3.2.4) as well as compiler settings for -std=c99 and -std=gnu99. Just understand that there are some limitations for the macro if it doesn't work as expected.

这篇关于在Objective-C中使用宏登录函数名和行号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆