所以这个答案Do I need to disable NSLog before release Application?提供了一个在生产环境中禁用NSLog的好方法,但不幸的是,这个解决方案似乎不适用于Swift项目。我的方法是将以下代码放在我用于项目中某些pod的桥接头.h文件中。
#ifdef DEBUG
#define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
#define DLog(...) do { } while (0)
#endif
但是,在Swift代码中使用DLog会导致编译器声明它们是未识别的符号。是否有其他地方我应该放置这个#ifdef
或者是否有一个不同的Swift项目解决方案?
答案 0 :(得分:41)
您需要设置编译器标志以使用Swift预处理器 - 转到Build Settings的 Swift编译器 - 自定义标志部分以设置-D DEBUG
标志:< / p>
然后在您的代码中,您可以定义DLog()
函数,并仅在设置DEBUG
标志时打印您的消息:
func DLog(message: String, function: String = #function) {
#if DEBUG
println("\(function): \(message)")
#endif
}
答案 1 :(得分:8)
我是一名非常初级的开发人员,需要更清楚地定义一些内容,以便随时跟进。我一直遇到类似问题的困难,取而代之的是println(),当我问这个问题时,我的查询被标记为这个问题的副本。
经过大量研究,试验,错误,错误,错误和错误!!后,我发现我需要遵循的顺序是:
-D DEBUG
,然后按返回以提交该行。将新的Swift文件添加到项目中。您将要为该文件创建自定义类,因此请按以下行输入文本:
class Log {
var intFor : Int
init() {
intFor = 42
}
func DLog(message: String, function: String = __FUNCTION__) {
#if DEBUG
println("\(function): \(message)")
#endif
}
}
(我今天很难让类init被Xcode接受,所以init可能比必要的重量级更重。)
现在,您需要在任何打算使用新自定义函数的类中引用您的自定义类来代替println()
在每个适用的类中将其添加为属性:
let logFor = Log()
现在,您可以将println()
的所有实例替换为logFor.DLog()
。输出还包括调用该行的函数的名称。
println()
对输入也更灵活一些,所以我无法在我的代码中的每个实例中使用它。答案 2 :(得分:6)
查看关于撰写断言here
的Apple Swift博客文章简而言之,答案是将DLog编写为:
func DLog(message:String, function:String = __FUNCTION__) {
#if !NDEBUG
NSLog("%@, %@", function, message)
#endif
}
答案 3 :(得分:1)
下面,我修改了上面给出的Nate Cook的答案。此版本适用于String
和NSString
个参数:
func DLog<T>(message:T, function: String = __FUNCTION__) {
#if DEBUG
if let text = message as? String {
print("\(function): \(text)")
}
#endif
}
当你需要做这样的事情时,它会很方便:
DLog("Received data:")
DLog(NSString(data:httpResponseBodyData, encoding:NSUTF8StringEncoding))
答案 4 :(得分:1)
#if DEBUG
#else
public func NSLog(_ format: String, _ args: CVarArg...)
{
// noop
}
#endif
导致此问题的任务:swift debugPrint vs print
答案 5 :(得分:0)
我刚刚发现了这个惊人的全局功能: https://gist.github.com/Abizern/a81f31a75e1ad98ff80d
这符合Nate Cook的答案,并且还会打印遇到的调试打印声明的文件名和行号。
答案 6 :(得分:0)
我同意uclagamer的答案,这本质上是一个包含在预处理器条件中的加强打印功能:
func gLog<T>(@autoclosure object: () -> T, _ file: String = __FILE__, _ function: String = __FUNCTION__, _ line: Int = __LINE__)
{
#if DEBUG
let value = object()
let stringRepresentation: String
if let value = value as? CustomDebugStringConvertible
{
stringRepresentation = value.debugDescription
}
else if let value = value as? CustomStringConvertible
{
stringRepresentation = value.description
}
else
{
fatalError("gLog only works for values that conform to CustomDebugStringConvertible or CustomStringConvertible")
}
let fileURL = NSURL(string: file)?.lastPathComponent ?? "Unknown file"
let queue = NSThread.isMainThread() ? "UI" : "BG"
let gFormatter = NSDateFormatter()
gFormatter.dateFormat = "HH:mm:ss:SSS"
let timestamp = gFormatter.stringFromDate(NSDate())
print("\(timestamp) \(queue) = \(fileURL) | \(function)[\(line)]: " + stringRepresentation)
#endif
}
这是针对Swift 2.0更新的。所有功劳都归功于Abider Nasir。他的原始博客文章(和链接的要点)可以在这里找到:
http://abizern.org/2015/02/01/debug-logging-in-swift/
重要说明:如果有人在努力寻找“Swift编译器 - 构建设置的自定义标志”部分,这已被提及很多次,您需要确保显示“所有”构建设置,而不仅仅是“基本”构建设置,默认情况下。
答案 7 :(得分:0)
纯魔法_isDebugAssertConfiguration()
完成所有内容,而不是与Custom Flags
相关的混乱:
func log<T>(argument: T, file: String = #file, line: Int = #line, function: String = #function) {
guard _isDebugAssertConfiguration() else {
return
}
let fileName = NSURL(fileURLWithPath: file, isDirectory: false).URLByDeletingPathExtension?.lastPathComponent ?? "Unknown"
print("\(fileName)@\(line)/\(function): \(argument)")
}
在此处查看有关它的更多信息(和选项):https://stackoverflow.com/a/34532569/496389。