Objective-C:从“Distribution”/生产构建中删除NSLog调用?

12 浏览
0 Comments

Objective-C:从“Distribution”/生产构建中删除NSLog调用?

更新:

这里有更多相关信息:

在生产代码中是否真的不应该使用NSLog()?

~~~~~~~~~~~~~~~~~~~~~~~~

情况

我在我的应用程序的复杂部分调试时,使用了一些相当庞大的NSLog调用。然而,最近我才了解到这些调用会影响运行时性能!

目标

我希望在任何不实际执行“Product > Run”(即Command-R)的情况下,都能够移除我的NSLog调用 - 尤其是在这个应用程序部署到App Store上时,以及在与Xcode断开连接时运行应用程序(例如,在街上走路时只是点击图标)。

提议的解决方案?

假设我已经创建了一个名为VIEW_DEBUG的预处理器宏,以下实现能否有效地在上述情况下移除NSLog调用?

    <一些代码>
#ifdef VIEW_DEBUG
    NSLog(@"非常复杂的日志条目");
#endif
    <更多的代码>

这对我来说很难“测试”,所以我想向更有经验的人求助。:)

Xcode设置(供参考)

xcode settings

0
0 Comments

Objective-C: 在发布版本中删除 'Distribution' 的 NSLog 调用

在开发过程中,我经常在代码中使用 DLog,它运行得很好。下面是我在代码中使用 DLog 的示例:

// DLog 几乎可以直接替换 NSLog

// DLog();

// DLog(@"here");

// DLog(@"value: %d", x);

// 不幸的是,DLog(aStringVariable) 并不能正常工作,你需要使用 DLog(@"%@", aStringVariable) 代替。

#ifdef DEBUG

# define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

#else

# define DLog(...)

#endif

// ALog 不受 DEBUG 设置的影响,始终会显示输出

#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

更多信息:The Evolution of a Replacement for NSLog

问题出现的原因:

这段代码中的 DLog 和 ALog 宏定义在 DEBUG 模式下会调用 NSLog,而在发布版本中不需要这些调试信息。因此,问题的出现是因为在发布版本中仍然存在 NSLog 的调用。

解决方法:

为了在发布版本中删除 NSLog 的调用,我们需要修改宏定义 DLog 和 ALog。我们可以使用预处理指令来判断当前代码是否处于 DEBUG 模式,并根据判断结果来定义 DLog 和 ALog 的行为。

解决方法如下:

#ifdef DEBUG

# define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

#else

# define DLog(...)

#endif

在发布版本中,我们可以通过在预处理指令中定义 NDEBUG 来禁用 DEBUG 模式。这样,所有的 DLog 和 ALog 调用都会被替换为空。

#ifdef NDEBUG

# define DLog(...)

# define ALog(...)

#endif

通过以上修改,我们可以在发布版本中删除 NSLog 的调用,从而提高应用程序的性能和安全性。

0
0 Comments

问题原因:在开发过程中,我们通常会使用NSLog来输出调试信息,但是在发布版本中,我们不希望包含这些调试信息。因此,我们需要一种方法来自动删除或禁用发布版本中的NSLog语句。

解决方法:一种常见的解决方法是在前缀文件中添加以下代码(或者您可以创建一个专用的类,然后在需要的地方#include它):

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

Xcode在执行调试构建时已经为我们定义了DEBUG(如您的屏幕截图所示)。`__VA_ARGS__`是一种在C99中引入的创建可变参数宏的方法。`do/while`确保即使DebugLog什么也不做,它仍具有相同的语法效果 - 不必担心无意义的循环,优化器将为您删除它。

然后,您可以像使用NSLog一样使用DebugLog。这样做与您提出的使用VIEW_DEBUG的方法完全相同,但您不需要一次又一次地复制和粘贴#ifdef条件。

`#define DebugLog(...) NSLog(__VA_ARGS__)`也可以工作。此外,对于GCC或LLVM,您不需要do {} while(0),`#define DebugLog(...)`也可以正常工作。

感谢两位评论者(尽管我无法同时@两位)- 这就是我从我打开的一个项目中盲目复制并粘贴所得到的。我接受了您的更正,并将其标记为社区wiki,因为现在它不会非常准确地声称对答案拥有所有权。

这就是它的基本含义 - 当定义了DEBUG时,您将获得一个行为与您键入NSLog完全相同的DebugLog(或任何您想要的名称),否则就会像您键入while(0)或什么也不写。它只取决于构建的类型,而不取决于设备是否连接,但它会阻止您发布日志,并且您无法从开发构建中对发布性能进行准确评估 - 这就是为什么当您使用Instruments进行性能分析时,它会自动执行发布构建的原因。

0