【问题标题】:Enable and Disable NSLog in DEBUG mode在 DEBUG 模式下启用和禁用 NSLog
【发布时间】:2011-09-26 23:43:33
【问题描述】:

我想在调试时启用 NSLog,否则禁用它。一个很简单的事情是:

#ifdef DEBUG
NSLog(@"My log");
#endif

但是所有这些#ifdef#endif 都很无聊...... :( 所以我尝试了其他东西:(.pch 是放置它的好地方)

#ifdef DEBUG
#   define NSLog(text) NSLog(text);
#else 
#   define NSLog(text) 
#endif

这项工作非常好(不是递归的)。但问题是 NSLog 有无限的参数。

void NSLog(NSString *format, ...)

如何解决这个问题以在预处理器模式下工作?

-- 编辑--

这段代码让你的 NSLog 变得更好:

#ifdef DEBUG
    #define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
    #define NSLog(...)
#endif

【问题讨论】:

  • +1 表示好问题。关于此主题的完整可重用组件mobile.tutsplus.com/tutorials/iphone/…
  • 我按照链接中的指南进行操作。但我收到以下编译错误:架构 x86_64 的未定义符号:ld:未找到架构 x86_64 的符号 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) 请帮助@MahbuburRAaman
  • @Gon, Error Undefined symbols for architecture x86_64: ld: symbol(s) not found for architecture x86_64 出现有几个原因。例如,对于缺少库或其他情况,请查看以下 SO 资源 stackoverflow.com/questions/18408531/…stackoverflow.com/questions/11996227/…stackoverflow.com/questions/6231368/…
  • @MahbuburRAaman 感谢您的回复。我发现原因是我从一个目标 c++ 文件中调用了这个自定义的 NSLog 方法。
  • 请问,我该把这段代码放在哪里?

标签: objective-c cocoa nslog


【解决方案1】:

这应该可以解决问题:

 #ifdef DEBUG
 #   define NSLog(...) NSLog(__VA_ARGS__)
 #else 
 #   define NSLog(...) (void)0
 #endif

【讨论】:

  • 没关系,但是替换 #define NSLog(...) NSLog(VA_ARGS); with #define NSLog(...) NSLog(VA_ARGS) (删除最后一个;)
  • @JustSid:如何设置或重置 DEBUG 标志?
  • 这不适合三元运算符。
  • @StianHøiland 虽然 void 周围的三元运算符是否是一个好主意值得怀疑,但我已经更新了代码以便它支持它。
【解决方案2】:

这有点短,并且在使用设备时也会禁用 NSLog。如果您正在编写游戏,经常发送 NSLog 可以将您的 FPS 从 60 降低到 20。

#if !defined(DEBUG) || !(TARGET_IPHONE_SIMULATOR)
    #define NSLog(...)
#endif

【讨论】:

    【解决方案3】:

    以上所有答案都是正确的。我也可以建议您按照以下方式进行操作。假设我有一个没有括号的 if 语句

    if(x==5)
    NSLog("x is 5");
    

    如果将 NSLog 替换为无语句会发生什么。所以我们可以简单地用一个空循环替换它。

    #ifdef DEBUG
    #define NSLog(...) NSLog(__VA_ARGS__)
    #else
    #define NSLog(...) do {} while (0)
    #endif
    

    此语句将运行一次空循环。这将从您的所有实时代码中安全地删除您的 NSLog。

    【讨论】:

    • 好点,这也是重复使用不带括号的if 语句可能首先是个坏主意的好地方。
    • 代码将被预处理为if (x==5) ;,这很好。
    • 这不适合三元运算符。
    • 如果您有一个包含在 .pch 中的通用常量文件,则将其放置在其中,否则您可以将其放在 @implementation 之前的类顶部
    【解决方案4】:
    #ifndef Debug
        #define Debug 1
    #endif
    
    #if Debug
    #   define DebugLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
    #else
    #   define DebugLog(...)
    #endif
    

    将 Debug 设置为 1 以启用日志,将其设置为 0 以禁用它。

    【讨论】:

    • 您可以创建常量头文件并将代码添加到其中,访问您只需导入头文件并使用DebugLog函数记录您想要的变量......跨度>
    【解决方案5】:

    这是一个不错的技巧... 添加到任何 .m

    #define EXTRANSLog if([[NSUserDefaults standardUserDefaults] boolForKey:@"SomeFancyKey"] == YES) NSLog 
    

    任意替换

    NSLog(@"????");
    

    EXTRANSLog(@"????");
    

    在此示例中,我创建了一个 NSUser 键并将 BOOL 设置为 YES,如果您不想通过控制台调试器查看 EXTRANSLog ,则使用某种形式的开关等将键更改为 NO 或完全删除。

    我在进行故障排除时使用它,并且不希望出现所有过多的日志。 仅当 SomeFancyKey == YES 时。

    这个和

    一样
    #define NSLog if(1) NSLog
    

    其中 1 是 YES 显示 NSLog,0 是 NO。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多