在 Xcode 中,有没有办法在调用 NSLog 时禁用调试器控制台中出现的时间戳?

Posted

技术标签:

【中文标题】在 Xcode 中,有没有办法在调用 NSLog 时禁用调试器控制台中出现的时间戳?【英文标题】:In Xcode, is there a way to disable the timestamps that appear in the debugger console when calling NSLog? 【发布时间】:2010-11-24 04:38:41 【问题描述】:

Xcode 的调试器控制台可以轻松查看我的应用使用 NSLog() 发出的任何调试消息,但它始终会在它们上面加上时间戳前缀:

2009-08-30 04:54:48.128 MyApp[94652:a0f] some log message
2009-08-30 04:54:50.647 MyApp[94652:a0f] another log message
...

这个前缀我没用,而且占用很多空间。我觉得它被硬编码到 Apple 的日志系统中,但以防万一有解决方案:

我可以让调试器控制台向我显示没有时间戳前缀的日志消息吗?

这样的东西会很完美:

some log message
another log message
...

【问题讨论】:

【参考方案1】:

NSLog() 是这样做的,而不是调试器控制台。

避免它的最简单方法是根本不使用 NSLog。您可以使用 fprintf(),但很痛苦,因为它不支持 %@ 格式类型。

我一般为此写一个函数:

void MyLog(NSString *format, ...) 
    va_list args;
    va_start(args, format);
    NSString *formattedString = [[NSString alloc] initWithFormat: format
                                                  arguments: args];
    va_end(args);
    [[NSFileHandle fileHandleWithStandardOutput]
        writeData: [formattedString dataUsingEncoding: NSNEXTSTEPStringEncoding]];


显然,修改它以添加换行符或使用更短的前缀等...

(修正了流浪的 ctrl-b)

【讨论】:

我必须使用[NSFileHandle fileHandleWithStandardOutput] 才能使其工作,但它确实成功了。谢谢! 抱歉——我在打字过程中按了 ctrl-b。固定的。 :) NSNEXTSTEPStringEncoding?不是NSUTF8StringEncoding 不合时宜;任你选。我发现——在过去——NeXTSTEP 编码会产生更少的不可打印字符。但是现在工具链中的 UTF8 支持要好得多。 ...StringEncoding] 后面缺少一个]【参考方案2】:

定义一个宏

#if __has_feature(objc_arc)
  #define MDLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
#else
  #define MDLog(format, ...) CFShow([NSString stringWithFormat:format, ## __VA_ARGS__]);
#endif

在你的代码中使用这个宏

NSLog(@"some log message");
MDLog(@"some log message");

这是控制台的输出

NSLog->2014-01-28 10:43:17.873 TestApp[452:60b] some log message MDLog -> some log message


附言

如果有人想要自定义日志,它可以为您提供更多信息,如方法名称/行号等,可以下载开源 MLog.h on GitHub

【讨论】:

【参考方案3】:

在你的.pch文件中输入这一行代码,你就完成了

#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

注意##部分

【讨论】:

试过这个,应用程序崩溃,出现错误:*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“*** -[NSPlaceholderString initWithFormat:locale:arguments:]: nil argument” ***第一掷调用堆栈:(0x30af2f83 0x3b36dccf 0x30af2ec5 0x3141013f 0x31410069 0x11ae7 0x1254b 0x6748d 0x3b855833 0x3b85581f 0x3b85c49f 0x30abd8a1 0x30abc175 0x30a26ebf 0x30a26ca3 0x35980663 0x3337314d 0x1e8d7 0xd8f0)的libc ++ abi.dylib:与未捕获的异常终止类型NSException(LLDB)跨度> 它对我有用,我在生产代码中使用它,看到那些赞成票它也一定对他们有用,我不确定你为什么会出现异常错误,公平地说,请不要告诉我你期望通过简单地粘贴你的错误调用堆栈来传达一些信息,没有上下文它的乱码,但代码是完美的 我将一行代码放入我的 .pch 文件并点击运行,这就是我得到的结果。'害怕我无法说出它的哪一部分可以解释崩溃。对 NSLog() 的调用之一是否负责?很高兴知道为什么,如果是这样的话。 @carelessChoosy:一个很棒的单行字,非常感谢。这应该是选定的答案。【参考方案4】:

结合 bbum 的回答继续使用 NSLog 的一种方法是使用预处理器宏将 NSLog 重新定义为您自己的函数

#define USECUSTOMLOGS 1
#if USECUSTOMLOGS
#define NSLog MyLog
#endif

这将在编译时将 NSLog 替换为 MyLog。基本上你可以在任何地方继续使用 NSLog,它仍然会为控制台窗口使用你的自定义格式。您也可以随时通过将 1 更改为 0 将其改回使用 NSLog。

【讨论】:

这听起来更好,但我是新手,我不知道如何编写 MyLog - 你能推荐任何链接,甚至是代码吗? @codingTheHole 你指的是MyLog的格式吗?【参考方案5】:

ARC 版本:

void NFLog(NSString *format, ...)

    va_list args;
    va_start(args, format);
    NSString *formattedString = [NSString stringWithFormat:format, args];
    formattedString = [formattedString stringByAppendingString:@"\n"];
    va_end(args);
    [[NSFileHandle fileHandleWithStandardOutput] writeData: [formattedString dataUsingEncoding: NSUTF8StringEncoding]];

更新:

我正在做的是将此代码添加到 xxx-Prefix.pch 然后你可以在任何地方使用它:

#define newLine         do  [(NSFileHandle*)[NSFileHandle fileHandleWithStandardOutput] writeData:[@"\n" dataUsingEncoding: NSUTF8StringEncoding]];  while(0);
#define NFLog(args,...) do  [(NSFileHandle*)[NSFileHandle fileHandleWithStandardOutput] writeData:[[NSString stringWithFormat:args, ##__VA_ARGS__] dataUsingEncoding: NSUTF8StringEncoding]];  while(0); newLine

如果你想要返回 NSLog:

#define NFLog(args,...) NSLog(args,##__VA_ARGS__)

【讨论】:

您可能希望将代码嵌入到伪造的 do while(0) sn-p: #define NFLog(args,...) do ...code... while(0); 由于中间有一个分号,如果在这样的代码中使用会导致问题:for (NSString* str in array) NFLog(str); 你是对的,添加假的do-while会很好。代码已更新。【参考方案6】:

在控制台窗口的左上角有一个下拉菜单,显示所有输出/调试器输出/目标输出。

选择目标输出。它适用于我的旧版本 Xcode,但老实说,它不适用于我当前的 4.3 版本。

希望对你有帮助。

JR

【讨论】:

【参考方案7】:

这比建议的解决方案要容易得多。使用不小心Choosy 的解决方案并添加更多内容以使其在发布版本上记录条目,只有您得到下面的宏。只需将此宏添加到您的标头或 .pch 文件中。当启用 DEBUG 标志时,此宏将显示日志条目,在发布版本中您将看不到日志条目。

#ifdef DEBUG
#define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#define Log(x, ...) NSLog(@"%s %d: " x, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define Log(x, ...)
#endif

【讨论】:

【参考方案8】:

清理日志宏

这是我为此目的制作的一个宏。它的工作方式与 NSLog 完全相同,但只有您的文本,没有额外的信息


宏(粘贴到您的 .h)

#define CLog(__string, ...) fprintf(stderr, "\n%s", [([NSString stringWithFormat:__string, ##__VA_ARGS__]) UTF8String])

使用示例:

CLog(@"I am %i days and %i years old", 3, 7);

日志:

I am 3 days and 7 years old

【讨论】:

以上是关于在 Xcode 中,有没有办法在调用 NSLog 时禁用调试器控制台中出现的时间戳?的主要内容,如果未能解决你的问题,请参考以下文章

没有 XCode 的应用程序的 NSLog 输出?

UIWebView 操作中的 NSLog(或其他监控事件)

Xcode 9,我的 NSLog() 去哪儿了?未在 Xcode 控制台或 Console.app 中显示

当我们在 Xcode 中执行程序时,有没有办法查看函数调用的顺序?

在 Xcode 中调用“touches-cancelled”方法

打印到 Xcode (XCTest) UITest 报告