Ios 在Swift项目中禁用用于生产的NSLog

Ios 在Swift项目中禁用用于生产的NSLog,ios,objective-c,swift,Ios,Objective C,Swift,因此,这个答案为在生产环境中禁用NSLog提供了一个很好的方法,但不幸的是,这个解决方案似乎不适用于Swift项目。我的方法是将下面的代码放在桥接头.h文件中,我在项目中的一些pod中使用该文件 #ifdef DEBUG #define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__]) #else #define DLog(...) do { } whil

因此,这个答案为在生产环境中禁用NSLog提供了一个很好的方法,但不幸的是,这个解决方案似乎不适用于Swift项目。我的方法是将下面的代码放在桥接头.h文件中,我在项目中的一些pod中使用该文件

#ifdef DEBUG
    #define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
#else
    #define DLog(...) do { } while (0)
#endif

但是,在Swift代码中使用DLog会导致编译器声明它们是未聚合的符号。是否有其他地方我应该把这个
#ifdef
放在其他地方,或者对于一般的Swift项目是否有不同的解决方案?

查看关于编写断言的苹果Swift博客条目

简单地说,答案是将DLog写成:

func DLog(message:String, function:String = __FUNCTION__) {
#if !NDEBUG
    NSLog("%@, %@", function, message)
#endif
}

您需要设置编译器标志以使用Swift预处理器-转到生成设置的Swift编译器-自定义标志部分以设置
-D调试
标志:

然后,您可以在代码中定义
DLog()
函数,并且仅当设置了
DEBUG
标志时才打印消息:

func DLog(message: String, function: String = #function) {
    #if DEBUG
    println("\(function): \(message)")
    #endif
}

我是一个相当初级的开发人员,有时需要更清晰地定义一些东西。我遇到了类似的问题,替换了println(),当我问这个问题时,我的询问被标记为这个问题的重复

经过大量的研究,尝试,错误,错误,错误,错误!!,我发现我需要遵循的顺序是:

  • 单击Xcode项目窗口左侧文件导航器顶部的项目名称。这是包含项目名称、有多少构建目标以及iOS SDK版本的行
  • 选择构建设置选项卡并向下滚动至底部附近的“Swift编译器-自定义标志”部分。单击其他标志旁边的向下箭头以展开该部分
  • 单击调试行选择它。将鼠标光标放在直线的右侧,然后双击。将出现一个列表视图。单击列表视图左下角的+按钮添加值。文本字段将变为活动状态
  • 在文本字段中,输入文本
    -D DEBUG
    ,然后按Return提交该行
  • 将新Swift文件添加到项目中。您需要为该文件创建自定义类,因此请按照以下行输入文本:

    class Log {
    
       var intFor : Int
    
      init() {
        intFor = 42
      }
    
      func DLog(message: String, function: String = __FUNCTION__) {
        #if DEBUG
          println("\(function): \(message)")
        #endif
      }
    }
    
  • (我今天很难让Xcode接受类init,所以init可能比需要的要重一些。)

  • 现在,您需要在任何类中引用您的自定义类,您打算在其中使用新的自定义函数来代替
    println()
    在每个适用的类中添加此属性:

       let logFor = Log()
    
  • 现在,您可以将
    println()
    的任何实例替换为
    logFor.DLog()
    。输出还包括调用该行的函数的名称

  • 请注意,在类函数中,除非我在该类中将该函数复制为类函数,否则无法调用该函数,
    println()
    的输入也更灵活,因此我不能在代码中的每个实例中都使用它

  • 我刚刚发现了这个惊人的全局函数:


    这与Nate Cook的答案相匹配,并额外打印遇到的调试打印语句的文件名和行号。

    下面,我已经修改了Nate Cook上面给出的答案。此版本适用于
    String
    NSString
    参数:

    func DLog<T>(message:T, function: String = __FUNCTION__) {
        #if DEBUG
            if let text = message as? String {
    
                print("\(function): \(text)")
            }
        #endif
    }
    

    我同意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
        }
    
    func gLog(@autoclosure object:()->T,u文件:String=u文件,u函数:String=u函数,u行:Int=u行)
    {
    #如果调试
    让值=对象()
    让stringRepresentation:String
    如果让值=值为?CustomDebugStringConvertible
    {
    stringRepresentation=value.debugDescription
    }
    否则,如果let value=值as?CustomStringConvertible
    {
    stringRepresentation=value.description
    }
    其他的
    {
    fatalError(“gLog仅适用于符合CustomDebugStringConvertible或CustomStringConvertible的值”)
    }
    让fileURL=NSURL(字符串:文件)?.lastPathComponent???“未知文件”
    让queue=NSThread.isMainThread()?“UI”:“BG”
    设gFormatter=NSDateFormatter()
    gFormatter.dateFormat=“HH:mm:ss:SSS”
    让timestamp=gFormatter.stringFromDate(NSDate())
    打印(“\(时间戳)\(队列)=\(文件URL)\(函数)[\(行)]:”+stringRepresentation)
    #恩迪夫
    }
    
    这是为Swift 2.0更新的。所有的功劳都归于阿比德·纳西尔。他的原始博文(以及链接的要点)可在以下位置找到:

    重要提示:如果有人正在努力寻找“Swift编译器-构建设置的自定义标志部分”,这已经被多次提到,那么您需要确保显示“所有”构建设置,而不仅仅是默认的“基本”构建设置


    纯魔法
    \u isDebugAssertConfiguration()
    执行所有操作,而不是执行与
    自定义标志相关的混乱:

    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)")
    }
    
    func日志(参数:T,文件:String=#文件,行:Int=#行,函数:String=#函数){
    guard _isDebugAssertConfiguration()其他{
    返回
    }
    让fileName=NSURL(fileURLWithPath:file,isDirectory:false).URLByDeletingPathExtension?.lastPathComponent???“未知”
    打印(“\(文件名)@\(行)/\(函数):\(参数)”)
    }
    
    请在此处查看有关它的更多信息(和选项):


    导致这一点的任务是:

    我实际上已经添加了
    -D DEBUG
    标志,不过还是要谢谢你。您建议我将此函数放置在何处,以便在全球范围内看到它?这种方法看起来很有用
    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)")
    }
    
    #if DEBUG
    #else
    public func NSLog(_ format: String, _ args: CVarArg...)
    {
        // noop
    }
    #endif