在发布应用程序之前我需要禁用 NSLog 吗?
当发布 iPhone 应用程序时,如果我禁用 NSLog();
它会表现得更好吗?
When releasing an app for iPhone, if I disable NSLog();
will it perform better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
一种方法是进入“构建”设置,并在“调试”配置下向“预处理器宏”值添加一个值,例如:
确保仅针对“调试”配置执行此操作,而不是针对“测试”或“发布”版本。然后,在通用头文件中,您可以执行以下操作:
现在,在任何地方都使用
DLog
,而不是NSLog
。测试和调试时,您将收到调试消息。当您准备好发布测试版或最终版本时,所有这些DLog
行会自动变为空,并且不会发出任何内容。这样就不需要手动设置变量或注释NSLogs
。选择你的构建目标就可以解决这个问题。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:
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:
Now instead of
NSLog
useDLog
everywhere. When testing and debugging, you'll get debug messages. When you're ready to release a beta or final release, all thoseDLog
lines automatically become empty and nothing gets emitted. This way there's no manual setting of variables or commenting ofNSLogs
required. Picking your build target takes care of it.Xcode 5 和 Xcode 的更新iOS 7
注意:对于在发布版本中删除 print() 语句的 Xcode 7 / Swift 2.1 解决方案,请找到我的答案 此处。
是的,您应该删除发布代码中的任何 NSLog 语句,因为它只会减慢您的代码速度,并且不会产生任何影响在发布版本中使用。幸运的是,在 Xcode 5 (iOS 7) 中,在发布版本中“自动”删除所有 NSLog 语句非常简单。那么为什么不这样做呢。
首先是要执行的 3 个步骤,然后是一些说明
1) 在 Xcode 项目中,找到“yourProjectName-prefix.pch”文件(通常您会在 main.m 文件所在的“支持文件”组下找到该文件)
2) 在“.pch”文件末尾添加以下 3 行:
3) 测试“调试”版本和“发布”版本之间的差异。一种方法是通过“编辑方案”-> '运行应用程序名称'->在“信息”选项卡下使用“调试”和“调试”之间的下拉框进行选择发布。在发布版本中,您将不会在调试控制台中看到任何 NSLog 输出!
这一切是如何运作的?
首先,我们必须知道预处理器相对“愚蠢”,仅在调用编译器之前充当“文本替换器”。它将用
#define
语句后面的内容替换“#define”中的任何内容。(...)
代表方括号 () 之间的“任何内容”。还要注意最后的;
。这并不是绝对必要的,因为编译器会优化它,但我喜欢把它放在那里,因为它更“正确”。在我们的#define
之后有“nothing”,因此预处理器会将其替换为“nothing”,因此它会丢弃从NSLog...
开始的完整行。 code> 直到并包括;
。可以使用
#ifdef
(如果已定义)或#ifndef
(如果未定义)来设置定义语句的条件,这里我们编写
#ifndef DEBUG
,其中表示“如果符号 DEBUG 未定义”。#ifdef
或#ifndef
需要用#endif
'关闭'Xcode 5 默认为我们定义了 'DEBUG' 符号。构建模式是“DEBUG”。在“发布”中,这没有定义。您可以在项目设置下验证这一点,选项卡“构建设置”->向下滚动到“Apple LLVM 5.0 - 预处理”部分 ->预处理器宏。您会看到符号“DEBUG”没有为发布版本定义!
最后,.pch 文件由 Xcode 自动创建,并在编译时自动包含在每个源文件中。因此,就好像您将整个
#define
内容放入每个源文件中。Update for Xcode 5 & iOS 7
note : for a Xcode 7 / Swift 2.1 solution to remove print() statements in a release build, find my answer here.
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.
First the 3 steps to take, then some explanation
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
2) add these 3 lines at the end of the '.pch' file :
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 !
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.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 atNSLog...
until and including the;
.define statements can be made conditional using
#ifdef
(if defined) or#ifndef
(if not defined)here we write
#ifndef DEBUG
, which means 'if the symbol DEBUG is not defined'. The#ifdef
or#ifndef
need to be 'closed' with#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 !
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.几乎所有上述答案都提出了解决方案,但没有解释问题。我用google搜索了一下,找到了原因。这是我的回答:
是的,如果你在发布版本中注释掉 NSLog,性能会变得更好。因为 NSLog 非常慢。 为什么? NSLog 会做两件事 1)将日志消息写入 Apple System Logging(ASL),2)如果应用程序在 xcode 中运行,它也会写入 stderr。
主要问题在于第一个问题。为了实现线程安全,每次调用 NSLog 时,它都会打开与 ASL 设施的连接,发送消息,然后关闭连接。连接操作非常昂贵。另一个原因是 NSLog 花费一些时间来获取要记录的时间戳。
参考来自此处。
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.
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.
Reference from here.
我个人最喜欢的是使用可变参数宏。
My personal favourite is to use a variadic macro.
除了所有明智地评论说在生产中根本不调用
NSLog()
运行速度稍快一些的人之外,我还要补充一点:所有这些
NSLog()
> 任何从商店下载您的应用程序并将设备插入运行 Xcode 的 Mac(通过管理器窗口)运行该应用程序的人都可以看到输出字符串。根据您记录的信息(尤其是您的应用联系服务器、进行身份验证等),这可能是一个严重的安全问题。
In addition to all the people who wisely commented that not calling
NSLog()
at all in production runs slightly faster, I'll add that: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).Depending on what information you log (and especially if your app contacts a server, does authentication, etc.), this can be a serious security issue.
在 Xcode 中项目的当前默认设置中,
NS_BLOCK_ASSERTIONS
宏将设置为发布版本为 1,调试版本为DEBUG=1
。所以,我更喜欢下面的方法。
Inside current default setting of project in Xcode, the
NS_BLOCK_ASSERTIONS
macro will be set to 1 in release version, andDEBUG=1
in Debug version.So, I prefer the following method.
是的,您应该禁用它。特别是当您试图最大限度地提高代码速度时。 NSLogging 左右的东西会污染其他开发人员可能试图挖掘的系统日志,它会对速度关键的代码(内部循环等)产生很大的影响。我不小心在递归函数中留下了一些日志消息,必须发布“速度提高 30%!”的更新几周后...;-)
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... ;-)
所有好的答案,但是您可以考虑使用另一个小技巧,主要是在应用程序的开发/测试阶段。
如果您只想关闭调试代码,而不是可能表明代码直接控制之外的问题的消息,那么它对于应用程序发布代码也很有用。
技巧:
您只需在 .m 文件顶部添加以下行即可关闭每个 .m 文件的 NSLog:(
注意:执行 不将其放入.h文件,仅放入.m文件!)
这只会使编译器通过扩展预处理器宏来评估
NSLog()
。该宏除了删除参数之外什么也不做。如果你想再次打开它,你可以随时使用
你可以通过执行类似的操作来阻止对特定方法组周围的 NSLog 的调用
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:
(NOTE: do NOT put this the .h file, only the .m file!)
This just makes the compiler evaluates
NSLog()
by expanding your preprocessor macro instead. The macro does nothing but strip out the arguments.if you want to turn it back on again you can always use
You could for example just prevent out calls to NSLog around a particular group of methods by doing something like
NSLog 速度很慢,不应该用于发布版本。像下面这样的简单宏将禁用它以及您可能拥有的任何断言,这些断言也应该被禁用。在不太常见的情况下,您确实希望在发布版本中使用 NSLog,只需直接调用它即可。不要忘记将“-DNDEBUG”添加到“其他 c 标志”构建设置中。
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.
在 pch 文件中,在 #endif 之前写下此内容
in pch file write down this before #endif
那这个呢?
what about this?
这也将接受额外的参数..
只需将 showDebugLogs 参数值设置为 true 或 false,根据您的需要
This will accept the additional arguments too..
Just the showDebugLogs parameter value to true or false, as per your need