Swift:print()vs println()vs NSLog()

printNSLogprintln什么区别,我应该什么时候使用它们?

例如,在Python中,如果我想打印一个字典,我只是print myDict ,但现在我有两个其他选项。 我应该如何和什么时候使用每个?

有一些差异:

  1. print vs println

    printfunction在debugging应用程序时在Xcode控制台中输出消息。

    println是Swift 2中删除的变体,不再使用。 如果您看到使用println旧代码,现在可以安全地将其replace为print

    回到Swift 1.x, print没有在打印的string的末尾添加换行符,而println做了。 但是现在, print总是在string的末尾添加换行符,如果你不想这样做,提供一个terminator参数""

  2. NSLog

    • NSLog速度较慢;

    • NSLog为输出添加时间戳和标识符,而print不会;

    • NSLog语句出现在设备的控制台和debugging器的控制台中,而print只出现在debugging器控制台中。

    • NSLog使用printf风格的格式string,例如

       NSLog("%0.4f", CGFloat.pi) 

      这将产生:

      2017-06-09 11:57:55.642328-0700 MyApp [28937:1751492] 3.1416

  3. 有效的iOS 10 / macOS 10.12中,还有第三种替代schemeos_log ,它是“统一日志logging”系统的一部分(请参阅WWDC 2016video统一日志logging和活动跟踪 )。

    • 在使用os_log函数之前,您必须先导入os.log

       import os.log 
    • NSLog一样, os_log也会向Xcodedebugging控制台和设备控制台输出消息

    • 您现在可以控制控制台应用程序中可用的“子系统”和“类别”字段。 例如:

       let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network") os_log("url = %@", log: log, url.absoluteString) 

      当您通过外部控制台应用程序观察应用程序时,不仅可以将这些列添加到主视图,还可以基于这些列进行过滤。 当想要将debugging消息与(a)代表您的应用程序的其他子系统生成的debugging消息区分开时,这非常有用; 或(b)来自其他类别或types的消息。

    • 您可以指定不同types的日志消息: .info.debug.error.fault (或.default ):

       os_log("web service did not respond", type: .error) 

      因此,如果使用外部控制台应用程序,则可以select仅查看特定类别的消息(例如,如果在控制台“操作”菜单上select“包含debugging消息”,则只显示debugging消息)。 这些设置也决定了事情是否logging到磁盘的许多细微问题的细节。 有关更多详情,请参阅WWDCvideo。

    • 使用os_log时不能使用string插值。 例如,你不能这样做:

       os_log("foo \(url.absoluteString)") 

      你将不得不这样做:

       os_log("url = %@", url.absoluteString) 
    • 上述限制的原因之一是支持数据隐私。 原始数据types(例如数字)是默认公开的,对象(例如string)默认是私有的。 在上一个loggingURL的例子中,如果应用程序是从设备本身调用的,并且您正在从Mac的控制台应用程序中观看,则会看到:

      url = <private>

      如果你想从外部设备看到它,你必须这样做:

       os_log("url = %{public}@", url.absoluteString) 
    • 请注意, NSLog现在使用统一的通知系统在幕后,但有以下警告:

      • 您无法控制子系统或类别或日志types;

      • 它不支持隐私设置。

底线, print足够简单的任务,但NSLog是有用的,因为它包括你的时间戳信息。

在debugging必须在Xcode以外testing的iOS应用程序时, os_log的function就os_log 。 例如,在testing后台iOS应用程序进程(如后台获取)时,连接到Xcodedebugging器会更改应用程序生命周期 。 所以,你经常需要testing物理设备,从设备本身运行应用程序,而不是从Xcode的debugging器启动应用程序。 统一日志logging让你仍然可以从macOS控制台应用程序中观看你的iOS设备os_log语句。

如果你正在使用Swift 2 ,现在只能使用print()来写输出。

苹果已经将println()print()函数合并为一个。

已更新至iOS 9

默认情况下,函数通过添加换行符来终止打印的行。

 print("Hello Swift") 

终结者

要打印一个没有换行符的值,传递一个空string作为终止符

 print("Hello Swift", terminator: "") 

分隔器

您现在可以使用分隔符连接多个项目

 print("Hello", "Swift", 2, separator:" ") 

或者你可以结合使用这种方式

 print("Hello", "Swift", 2, separator:" ", terminator:".") 

而且,Swift 2有debugPrint() (和CustomDebugStringConvertible协议)!

不要忘了debugPrint() ,其工作方式与print()相似,但最适合debugging

例子:

  • string
    • print("Hello World!")变成Hello World
    • debugPrint("Hello World!")变成"Hello World" (行情!)
  • 范围
    • print(1..<6)变为1..<6
    • debugPrint(1..<6)变为Range(1..<6)

任何类都可以通过CustomDebugStringConvertible协议自定义它们的debuggingstring表示CustomDebugStringConvertible

为了增加Rob的回答,从iOS 10.0开始,Apple推出了全新的“统一日志logging”系统,取代了现有的日志logging系统(包括ASL和Syslog,NSLog),并且由于其新的技术而超越了现有的日志logging方法logging数据压缩和延迟数据收集。

从苹果 :

统一的日志logging系统提供了一个单一的,高效的,高性能的API,用于在系统的各个层面捕获消息。 这个统一的系统将日志数据的存储集中在内存和磁盘上的数据存储中。

苹果公司强烈build议使用os_log来logging各种信息,包括信息,debugging,错误信息,因为与以前的日志系统相比,它的性能有了很大的提高,集中的数据收集使开发人员能够方便地进行日志和活动检查。 实际上,新系统的占用空间可能非常小,如果插入日志logging命令,则不会导致bug被消除的“观察者效应”,从而干扰发生错误的时间。

活动追踪的性能,现在是新的统一记录系统的一部分

你可以在这里详细了解这个。

综上所述:为了方便起见,使用print()进行个人debugging(但在部署在用户设备上时不会logging消息)。 然后,尽可能使用统一日志logging( os_log )。

还有另外一个叫做dump()方法,它也可以用于日志logging:

 func dump<T>(T, name: String?, indent: Int, maxDepth: Int, maxItems: Int) 

将对象的内容使用其镜像转储到标准输出。

从Swift标准库函数