2

我发现了一堆关于如何使用 NSLog 作为基础并添加PRETTY_FUNCLINE的宏变体,但这些宏的所有变体只是将结果输出到控制台。

我想要一个宏,它可以采用具有可变数量参数的格式,添加方法的名称和调用它的行号,然后返回一个 NSString 但到目前为止,编译器总是抱怨我调用它的地方. 我的最新版本如下:

#define FileLog(format, ...) {\
return [NSString stringWithFormat:@"\n  %s [Line %d] \n       %@",
__PRETTY_FUNCTION__,
__LINE__,
[NSString stringWithFormat:(format), ##__VA_ARGS__]];\
}

每次我从代码中调用它时,编译器都会生成以下错误之一:

error: expected expression before '{' token

我不想为此编写日志类或使用框架。必须有办法用宏来做到这一点?任何人?

提前致谢!

4

3 回答 3

8

这完全可以通过宏来实现,我认为您只需要更多关于它们的背景知识。

首先,宏不是函数,所以大括号是不必要的(事实上,是你的错误的原因)。宏实际上是一个相当愚蠢的“复制/粘贴”,由预处理器自动执行,使用它可以理解的语法。

为了定义一个跨越多行的宏并“就地”创建一个 NSString,您必须使用反斜杠转义换行符,如下所示:

#define FileLog(format, ...) \
    [NSString stringWithFormat:@"\n %s [Line %d] \n %@", \
    __PRETTY_FUNCTION__, \
    __LINE__, \
    [NSString stringWithFormat:format, ##__VA_ARGS__]]

宏不会像函数那样“返回”,因为正如我所提到的,它们只是“复制/粘贴”文本的一种方式。

你可以像这样使用它:

int num = 42;
NSLog(@"%@", FileLog(@"some number: %d", num));

如果您要查看预处理器输出(预处理器在编译之前创建的文件),上面的示例将扩展为:

NSLog(@"%@", [NSString stringWithFormat:@"\n %s [Line %d] \n %@", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:@"some number: %d", num]]);
于 2012-04-17T22:03:06.500 回答
2

试试这个....

创建包含文件

#define LOG_NOLOG_LEVEL 0
#define LOG_ERROR_LEVEL 1
#define LOG_WARN_LEVEL 2
#define LOG_INFO_LEVEL 3
#define LOG_DEBUG_LEVEL 4


#if LOG_HELPER_LEVEL >= LOG_DEBUG_LEVEL
    #define LOGDEBUG(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
    #define LOGDEBUG(...)
#endif

#if LOG_HELPER_LEVEL >= LOG_INFO_LEVEL
    #define LOGINFO(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
    #define LOGINFO(...)
#endif

#if LOG_HELPER_LEVEL >= LOG_WARN_LEVEL
    #define LOGWARN(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
    #define LOGWARN(...)
#endif

#if LOG_HELPER_LEVEL >= LOG_ERROR_LEVEL
    #define LOGERROR(...) {[LogHelper log:[NSString stringWithFormat:__VA_ARGS__]];}
#else
    #define LOGERROR(...)
#endif

然后用单个类方法创建一个简单的类 LogHelper 如下....

+ (void) log:(NSString *)message
{
    fputs([message cStringUsingEncoding:NSUTF8StringEncoding], stderr);
}

然后在您的代码中,您可以调用...

LOGDEBUG(@"%s - %d Redirect response received\n%@",__FILE__,
                                __LINE__,[redirectRequest dumpInfo]);

您可以将 LOG_HELPER_LEVEL 设置为您想要生成的日志记录级别。如果您将级别设置为 LOG_WARN_LEVEL,那么您的应用程序中将不会包含用于 INFO 或 DEBUG 级别的代码,因此很容易打包您的应用程序以供发布。

希望这可以帮助...

于 2012-04-17T22:11:42.017 回答
0

来自Viraj Thenuwara,他是我培训我的 iOS 高级开发人员 :-)

这个宏的定义和用法比上面提到的要简单得多。

#define debug                   1

#if debug
    #define AppLog(fmt, ...)        NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
    #define AppLog(...)
#endif

它的用法如下:

 NSString *url = @"http://google.com";    
 AppLog(@"url %@ and id %d", url, 5);

This AppLog line will print out it's given content only if the debug constant is equal to 1. At the Production time or in anytime you don't want to print the log lines you can disable it by turning that 1 into 0.

And it's console out put will be seen as follows:

enter image description here

Hope this will be helpful to someone else! Cheers!

于 2015-03-28T18:58:54.013 回答