55

我习惯于编程和查看日志消息。我知道您曾经能够NSLog()在调试 Cocoa 应用程序时使用它来跟踪消息。在 iPhone Xcode 开发环境中编码时“跟踪”消息的最佳方式是什么?

4

6 回答 6

215

在 Xcode 中有一种更方便的方式来跟踪日志消息,那就是使用断点操作。

在您想添加 printf 或 NSLog 的代码行上,设置一个断点,然后按住 Control 键单击它并选择“编辑断点”。在出现的蓝色气泡中,单击右侧的 + 按钮打开断点操作: 替代文本 http://idisk.mac.com/cdespinosa/Public/Breakpoint%20Actions.png

在此处输入您的日志文本。任何可以在调试器中打印的表达式都可以在用 @ 符号分隔时使用。

对于调试 Objective-C,通常更有用的是从弹出窗口中选择“Debugger Command”并输入“po [[object method] method]”来打印 Objective-C 对象的描述字符串或方法调用的结果。

确保单击右上角的“继续”复选框,以便在日志后继续执行。

这比 NSLog 和 printf 的优点:

  • 它在飞行中。您无需重新编译和重新启动即可添加或编辑日志消息。这可以为您节省大量时间。
  • 您可以有选择地启用和禁用它们。如果您从其中学到了足够多的东西,但它的喷吐干扰,只需取消选中它的启用框。
  • 所有输出都在您的 Mac 上生成,而不是在 iPhone 上生成,因此您不必事后下载和解析日志。
  • 在您的应用程序中发送控制台喷吐的机会显着降低。

另请查看“发言”按钮;它非常适合调试无法查看调试日志的全屏应用程序。

于 2009-02-19T17:55:38.960 回答
9

这是我在网上某处找到的大量代码。它定义了新函数 DLog() 和 ALog()。DLog 消息仅在使用 -DDEBUG 标志(定义 DEBUG)编译应用程序时出现。ALog 消息总是出现(即使在发布模式下)。

// DLog is almost a drop-in replacement for NSLog
// DLog();
// DLog(@"here");
// DLog(@"value: %d", x);
// Unfortunately this doesn't work DLog(aStringVariable); you have to do this instead DLog(@"%@", aStringVariable);
#ifdef DEBUG
#       define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#       define DLog(...)
#endif

// ALog always displays output regardless of the DEBUG setting
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
于 2010-03-12T17:21:28.947 回答
4

在我的项目中,我有一个基于DebugOutput.m的定制解决方案,这会将文件和行号添加到调试输出中,从而更容易识别输出文本的来源,同时仍然保持简短。

我使用调试掩码增强了标准解决方案,以便我可以为我的应用程序中的特定功能区域打开和关闭调试。在 Debug.h 中,我有

typedef enum {
kDebugMaskAp- = 1,
kDebugMaskXMLParser = 1 << 1,
kDebugMaskNetwork = 1 << 2,
kDebugMaskAnalytics = 1 << 3,
kDebugMaskCache = 1 << 4,
} debugBitMask;

#define debugForComponent(mask,format,...) if( currentDebugMask() & mask) [[DebugOutput sharedDebug]  output:__FILE__ lineNumber:__LINE__ input:(format), ##__VA_ARGS__]

在 Debug.m

-(void)output:(char*)fileName lineNumber:(int)lineNumber input:(NSString*)input, ...
{
  va_list argList;
  NSString *filePath, *formatStr;

  // Build the path string
  filePath = [[NSString alloc] initWithBytes:fileName length:strlen(fileName) encoding:NSUTF8StringEncoding];

  // Process arguments, resulting in a format string
  va_start(argList, input);
  formatStr = [[NSString alloc] initWithFormat:input arguments:argList];
  va_end(argList);

  // Call NSLog, prepending the filename and line number
  NSLog(@"File:%s Line:%d %@",[((DEBUG_SHOW_FULLPATH) ? filePath : [filePath lastPathComponent]) UTF8String], lineNumber, formatStr);

  [filePath release];
  [formatStr release];
}

在应用程序中,调用看起来像这样:

debugForComponent(kDebugMaskApp,@"Request failed - error %@", [error localizedDescription]);
于 2009-02-18T08:46:56.060 回答
2

将此粘贴到您的前缀标题中。项目中的所有日志肯定会消失。

#ifndef __OPTIMIZE__

#    define NSLog(...) NSLog(__VA_ARGS__)

#else

#    define NSLog(...) {}

#endif
于 2011-04-28T06:58:21.390 回答
0

您可以使用NSLogger,它带来的不仅仅是记录您的消息。我使用宏来禁用发布版本中的日志,同时让它们中的每一个都在调试版本中处于活动状态。日志量不是问题,因为 NSLogger 提供了强大的日志过滤选项。

于 2011-11-01T09:07:43.963 回答
-2

我只是使用替换所有功能....

我通过将 NSLog(@" 替换为 //***NSLog(@"

这样我就可以用 //***NSLog(@" 简单地找到它(在所有项目文件中使用 find )并重新启用它们

没什么花哨的,但它有效:)

于 2009-02-25T20:56:35.253 回答