ios 我需要在发布应用程序之前禁用 NSLog 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2025471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do I need to disable NSLog before release Application?
提问by RAGOpoR
When releasing an app for iPhone, if I disable NSLog();
will it perform better?
在发布 iPhone 应用程序时,如果我禁用NSLog();
它会表现得更好吗?
回答by Ramin
One way to do it is to go into your Build settings and under the Debug configuration add a value to "Preprocessor Macros" value like:
一种方法是进入您的构建设置并在调试配置下向“预处理器宏”值添加一个值,例如:
DEBUG_MODE=1
Make sure you only do this for the Debug configuration and not for Beta or Release versions. Then in a common header file you can do something like:
确保您只对调试配置执行此操作,而不对 Beta 或 Release 版本执行此操作。然后在通用头文件中,您可以执行以下操作:
#ifdef DEBUG_MODE
#define DLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog( s, ... )
#endif
Now instead of NSLog
use DLog
everywhere. When testing and debugging, you'll get debug messages. When you're ready to release a beta or final release, all those DLog
lines automatically become empty and nothing gets emitted. This way there's no manual setting of variables or commenting of NSLogs
required. Picking your build target takes care of it.
现在而不是到处NSLog
使用DLog
。在测试和调试时,您将收到调试消息。当您准备发布 Beta 版或最终版时,所有这些DLog
行都会自动变为空,并且不会发出任何内容。这样就不需要手动设置变量或注释NSLogs
所需的。选择你的构建目标会照顾到它。
回答by Ronny Webers
Update for Xcode 5 & iOS 7
Xcode 5 和 iOS 7 的更新
note : for a Xcode 7 / Swift 2.1solution to remove print()statements in a release build, find my answer here.
注意:对于在发布版本中删除print()语句的Xcode 7 / Swift 2.1解决方案,请在此处找到我的答案。
Yes, you should remove any NSLog statement in your release code, as it just slows down your code, and isn't of any use in a release version. Fortunately, in Xcode 5 (iOS 7), it is amazingly simple to remove all your NSLog statements 'automatically' in release builds. So why not do it.
是的,您应该删除发布代码中的任何 NSLog 语句,因为它只会减慢您的代码速度,并且在发布版本中没有任何用处。幸运的是,在 Xcode 5 (iOS 7) 中,在发布版本中“自动”删除所有 NSLog 语句非常简单。那么为什么不这样做呢。
First the 3 steps to take, then some explanation
首先是要采取的 3 个步骤,然后是一些解释
1) in your Xcode project, locate the 'yourProjectName-prefix.pch' file (normally you'll find this under the group 'supporting files', where your main.m file is located
1) 在您的 Xcode 项目中,找到“yourProjectName-prefix.pch”文件(通常您会在“支持文件”组下找到它,您的 main.m 文件所在的位置
2) add these 3 lines at the end of the '.pch' file :
2) 在 '.pch' 文件的末尾添加这 3 行:
#ifndef DEBUG
#define NSLog(...);
#endif
3) test the difference between your 'debug' and 'release' version. One way to do this is through 'edit scheme' -> 'run app name' -> under the tab 'info' select using the drop-down box between debug & release. In the release version you won't see any NSLog output in the debug console !
3) 测试您的“调试”和“发布”版本之间的差异。一种方法是通过“编辑方案”->“运行应用程序名称”-> 在“信息”选项卡下使用调试和发布之间的下拉框进行选择。在发布版本中,您将不会在调试控制台中看到任何 NSLog 输出!
How does this all work?
这一切是如何运作的?
first of all, one must know that a preprocessor is relatively 'dumb', and just acts as a 'text replacer' before the compiler is called. It replaces anything you '#define' by what follows the #define
statement.
首先,必须知道预处理器相对“愚蠢”,并且在调用编译器之前仅充当“文本替换器”。它用#define
语句后面的内容替换您“#define”的任何内容。
#define NSLog(...);
The (...)
stands for 'anything' between the brackets (). Mind also the ;
at the end. This is not strictly necessary as the compiler will optimize this away, but I like to put it there, as it is more 'correct'. After our #define
there is 'nothing', so the preprocessor will replace it with 'nothing', and so it will just throw away the complete line, starting at NSLog...
until and including the ;
.
该(...)
代表的括号“什么”()。心也;
末。这不是绝对必要的,因为编译器会优化它,但我喜欢把它放在那里,因为它更“正确”。在我们#define
有“无”之后,因此预处理器将用“无”替换它,因此它只会丢弃完整的行,从NSLog...
直到并包括;
.
define statements can be made conditional using #ifdef
(if defined) or #ifndef
(if not defined)
可以使用#ifdef
(如果已定义)或#ifndef
(如果未定义)来使定义语句有条件
here we write #ifndef DEBUG
, which means 'if the symbol DEBUG is not defined'. The #ifdef
or #ifndef
need to be 'closed' with #endif
这里我们写#ifndef DEBUG
,意思是“如果符号 DEBUG 没有定义”。在#ifdef
或#ifndef
将需要“封闭”与#endif
Xcode 5 defines by default the 'DEBUG' symbol for us when de build mode is 'DEBUG'. In 'release' this is not defined. you can verify this under your project settings, tab 'Build settings' -> scroll down to the section 'Apple LLVM 5.0 - Preprocessing' -> preprocessor macros. You'll see that the symbol 'DEBUG' is not defined for release builds !
当 de 构建模式为“DEBUG”时,Xcode 5 默认为我们定义了“DEBUG”符号。在“发布”中,这没有定义。您可以在项目设置下验证这一点,选项卡“构建设置”-> 向下滚动到“Apple LLVM 5.0 - 预处理”部分-> 预处理器宏。你会看到符号“DEBUG”没有为发布版本定义!
finally, the .pch file is created by Xcode automatically, and automatically included in every source file during the compilation time. So it is as if you would have put the whole #define
thing into each of your source files.
最后,.pch 文件由 Xcode 自动创建,并在编译期间自动包含在每个源文件中。因此,就好像您会将整个#define
内容放入每个源文件中一样。
回答by Andrew
Almost all above answers sugest a solution but not explain the problem. I did a search in google, and found the reason. Here is my answer:
几乎所有上述答案都提出了解决方案,但没有解释问题。我在谷歌搜索了一下,找到了原因。这是我的回答:
Yes, if you comment out NSLog in your release version, the performance will become better. Because NSLog is pretty slow.Why? NSLog will do two things 1) write log messages to Apple System Logging(ASL), 2) if the app runs in xcode it write to stderr too.
是的,如果你在你的发布版本中注释掉 NSLog,性能会变得更好。因为 NSLog 很慢。为什么?NSLog 将做两件事 1) 将日志消息写入 Apple System Logging(ASL),2) 如果应用程序在 xcode 中运行,它也会写入 stderr。
The main problem lays in the first one. In order to achieve thread safe, every time NSLog is called, it opens an connection to ASL facility, sends message, and closes the connection. The connection operation is very expensive. Another reason is that NSLog spends some time to get the timestamp to log.
主要问题出在第一个。为了实现线程安全,每次调用 NSLog 时,它都会打开一个到 ASL 工具的连接,发送消息,然后关闭连接。连接操作非常昂贵。另一个原因是 NSLog 花费一些时间来获取要记录的时间戳。
Reference from here.
从这里参考。
回答by Eytan
My personal favourite is to use a variadic macro.
我个人最喜欢使用可变参数宏。
#ifdef NDEBUG
#define NSLog(...) /* suppress NSLog when in release mode */
#endif
回答by Nicolas Miari
In addition to all the people who wisely commented that not calling NSLog()
at all in production runs slightly faster, I'll add that:
除了所有明智地评论说NSLog()
在生产中根本不调用运行速度稍快的人之外,我还要补充一点:
All those NSLog()
output strings are visible to anyone who downloads your app from the store and runs it with the device plugged into a mac running Xcode(through the Organizer window).
所有这些NSLog()
输出字符串对于从商店下载您的应用程序并使用插入运行 Xcode 的 Mac 的设备运行它的任何人都是可见的(通过管理器窗口)。
Depending on what information you log (and especially if your app contacts a server, does authentication, etc.), this can be a serious security issue.
根据您记录的信息(特别是如果您的应用程序联系服务器、进行身份验证等),这可能是一个严重的安全问题。
回答by AechoLiu
Inside current default setting of project in Xcode, the NS_BLOCK_ASSERTIONS
macro will be set to 1 in release version, and DEBUG=1
in Debug version.
在 Xcode 中项目的当前默认设置中,NS_BLOCK_ASSERTIONS
宏将在发布版本和DEBUG=1
调试版本中设置为 1 。
So, I prefer the following method.
所以,我更喜欢下面的方法。
// NS_BLOCK_ASSERTIONS is defined by default, as shown in the screenshot above.
// Or, you can define yourself Flags in the `Other C Flags` -> `Release`.
#ifndef NS_BLOCK_ASSERTIONS
#define _DEBUG
#endif
#ifdef _DEBUG
// for debug mode
#define DLog(fmt,...) NSLog(@"%s " fmt, __FUNCTION, ##__VA_ARGS__)
... /// something extra
#else
// for release mode
#define DLog(fmt,...) /* throw it away */
... /// something extra
#endif
回答by Ben Gotow
Yes, you should disable it. Especially if you're trying to maximize the speed of your code. NSLogging things left and right pollutes the system log that other developers might be trying to dig through and it can have a big impact on speed-critical code (inside loops, etc..) I accidentally left some log messages in a recursive function once and got to release an update with a "30% speed increase!" a few weeks later... ;-)
是的,你应该禁用它。特别是如果您想最大限度地提高代码的速度。NSLogging 的东西左右污染了其他开发人员可能试图挖掘的系统日志,它可能对速度关键的代码(内部循环等)产生重大影响。我不小心在递归函数中留下了一些日志消息,然后必须发布“速度提高 30%”的更新!几周后... ;-)
回答by unsynchronized
All good answers, however here's another little trick you can consider using, mainly in the development/testing phases of your app.
所有好的答案,但是这里有另一个你可以考虑使用的小技巧,主要是在你的应用程序的开发/测试阶段。
It could also be useful for app release code also, if you only want to turn of YOUR debug code, and not messages that might indicate issues outside of your code's direct control.
如果您只想关闭调试代码,而不是可能指示代码直接控制之外的问题的消息,它也可用于应用程序发布代码。
The Trick:
诀窍:
You can turn off NSLog per .m file by simply including the follow line at the top of the .m file:
您可以通过简单地在 .m 文件的顶部包含以下行来关闭每个 .m 文件的 NSLog:
#define NSLog(...)
(NOTE: do NOTput this the .h file, only the .m file!)
(注意:不要把这个放在 .h 文件中,只放在 .m 文件中!)
This just makes the compiler evaluates NSLog()
by expanding your preprocessor macro instead. The macro does nothing but strip out the arguments.
这只是NSLog()
通过扩展预处理器宏来使编译器进行评估。宏除了去除参数之外什么都不做。
if you want to turn it back on again you can always use
如果你想再次打开它,你可以随时使用
#undef NSLog
You could for example just prevent out calls to NSLog around a particular group of methods by doing something like
例如,您可以通过执行类似的操作来阻止对特定方法组周围的 NSLog 调用
#define NSLog(...)
-(void) myProblematicMethodThatSometimesNeedsDebugging {
...
}
#undef NSLog
回答by papahabla
NSLog is slow and should not be used for release builds. A simple macro like the one below will disable it along with any asserts you might have which should also be disabled. In the less common case where you do want NSLog in a release build, just call it directly. Don't forget to add "-DNDEBUG" to your "other c flags" build settings.
NSLog 很慢,不应该用于发布版本。像下面这样的简单宏将禁用它以及您可能拥有的任何断言,这些断言也应该被禁用。在不太常见的情况下,您确实希望在发布版本中使用 NSLog,只需直接调用它。不要忘记将“-DNDEBUG”添加到“其他 c 标志”构建设置中。
#ifdef NDEBUG
#define MYLog(f, ...)
#else
#define MYLog(f, ...) NSLog(f, ## __VA_ARGS__)
#endif
回答by Sandeep Saurabh
in pch file write down this before #endif
在 pch 文件中,在 #endif 之前写下这个
#define NSLog() //