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

时间:2014-09-20 16:59:14

标签: swift debugging logging console

printNSLogprintln之间的区别是什么?我应该在何时使用它们?

例如,在Python中,如果我想打印字典,我只是print myDict,但现在我有2个其他选项。我应该如何以及何时使用它们?

6 个答案:

答案 0 :(得分:661)

一些差异:

  1. print vs println

    print函数在调试应用程序时在Xcode控制台中打印消息。

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

    回到Swift 1.x,print没有在打印字符串的末尾添加换行符,而println却没有。但是现在,print总是在字符串的末尾添加换行符,如果您不希望它这样做,请提供terminator ""参数。< / p>

  2. NSLog

    • NSLog速度较慢;

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

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

    • NSLog使用printf - 样式格式字符串,例如

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

      将产生:

        

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

  3. 有效的iOS 10 / macOS 10.12,还有第三种选择,os_log,是统一记录的第三部分&#34;系统(参见WWDC 2016视频Unified Logging and Activity Tracing)。

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

      import os.log
      
    • NSLog类似,os_log也会向Xcode调试控制台和设备控制台输出消息

    • 您现在可以控制&#34;子系统&#34;和&#34;类别&#34;控制台应用中可用的字段。例如:

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

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

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

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

      因此,如果使用外部控制台应用程序,您可以选择仅查看某些类别的消息(例如,如果您选择&#34;包括调试消息&#34;仅在控制台上显示调试消息&#34;操作&# 34;菜单)。这些设置还规定了许多关于事物是否记录到磁盘的细微问题。有关详细信息,请参阅WWDC视频。

    • 使用os_log时,不能使用字符串插值。例如,你做不到:

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

      你必须这样做:

      os_log("url = %@", url.absoluteString)
      
    • 上述限制的原因之一是支持数据隐私。默认情况下,原始数据类型(例如数字)是公共的,对象(例如字符串)是私有的。在上一个记录URL的示例中,如果应用程序是从设备本身调用的,并且您正在从Mac的控制台应用程序中观看,那么您将看到:

        

      url =&lt; private&gt;

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

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

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

      • 它不支持隐私设置。

  4. 底线,print足以完成简单的任务,但NSLog非常有用,因为它包含了您的时间戳信息。

    在调试必须在Xcode之外进行测试的iOS应用程序时,os_log的强大功能显而易见。例如,在测试后台iOS应用程序进程(如后台提取)时,连接到Xcode调试器changes the app lifecycle。因此,您经常需要在物理设备上进行测试,从设备本身运行应用程序,而不是从Xcode的调试器启动应用程序。统一日志记录让您仍然可以从macOS控制台应用程序中查看您的iOS设备os_log语句。

答案 1 :(得分:74)

如果您正在使用 Swift 2 ,那么现在只能使用print()将内容写入输出。

  

Apple已将 println() print()功能合并到   之一。

已更新至iOS 9

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

print("Hello Swift")

<强>终止

要在其后打印没有换行符的值,请将空字符串作为终止符

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

<强>分隔

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

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

<强>两个

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

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

答案 2 :(得分:60)

此外,Swift 2有debugPrint()(和CustomDebugStringConvertible协议)!

不要忘记debugPrint(),其工作方式与print()相同,但most suitable for debugging

示例:

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

任何类都可以通过 CustomDebugStringConvertible 协议自定义其调试字符串表示。

答案 3 :(得分:31)

为了增加Rob的答案,自iOS 10.0以来,Apple推出了一个全新的“统一记录”系统,该系统取代了现有的记录系统(包括ASL和Syslog,NSLog),并且在性能上也超越了现有的记录方法,这要归功于它新技术包括日志数据压缩和延迟数据收集。

来自Apple

  

统一日志记录系统提供单一,高效,高性能的API,用于捕获跨系统所有级别的消息传递。这个统一的系统将日志数据的存储集中在内存和磁盘上的数据存储中。

Apple强烈建议使用import maya.cmds as mc #Create and place Spiral DNA elements for x in range (0,20): strandLName = "strandL" +str(x) nucleoName = "nucleo" +str(x) strandRName = "strandR" +str(x) strandL,strandHistory = mc.polySphere(name=strandLName, ch=1) nucleo,nucleoHistory = mc.polyCylinder(name=nucleoName, ch=1) mc.setAttr(nucleoName + '.translateX', 5) mc.setAttr(nucleoName + '.rotateZ', -90) mc.setAttr(nucleoName + '.scaleX', 0.5) mc.setAttr(nucleoName + '.scaleY', 5) mc.setAttr(nucleoName + '.scaleZ', 0.5) strandR,strandHistory = mc.polySphere(name=strandRName, ch=1) mc.setAttr(strandRName + '.translateX', 10) mc.select(deselect=1) #create empty group grp = mc.group(n=strandLName + 'NULL', em=1) mc.select(deselect=1) #Parent Elements to Group nucleotide = mc.parent(strandL, nucleo, strandR, grp)[0] #Move and rotate groups mc.setAttr(grp + '.translateX', -5.5) mc.xform(grp, cp=1) mc.setAttr(grp + ".translateY", x * 2) mc.setAttr(grp + ".ry", 15 * x) mc.select(deselect=1) 来记录各种消息,包括信息,调试,错误消息,因为与以前的日志记录系统相比,它的性能大大提高,并且集中式数据收集可以方便地记录日志和活动检查开发人员。实际上,新系统的占用空间可能很小,如果插入日志记录命令,干扰错误发生的时间,它就不会导致“观察者效应”,即你的错误消失。

Performance of Activity Tracing, now part of the new Unified Logging system

您可以在详细信息here中了解详情。

总结一下:为方便起见,请使用os_log进行个人调试(但在用户设备上部署时不会记录消息)。然后,尽可能使用统一日志记录(print())。

答案 4 :(得分:3)

另一个名为dump()的方法也可以用于记录:

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

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

来自Swift Standard Library Functions

答案 5 :(得分:0)

  1. NSLog-添加元信息(如时间戳和标识符),并允许您输出 1023个符号。还将消息打印到控制台中。最慢的方法
@import Foundation
NSLog("SomeString")
  1. print-将 all 字符串输出到Xcode。比以前有更好的表现
@import Foundation
print("SomeString")
  1. println(仅适用于Swift v1),并在字符串末尾添加\n
  2. os_log(从iOS v10开始)-打印 32768符号也会打印到控制台。比以前有更好的表现
@import os.log
os_log("SomeIntro: %@", log: .default, type: .info, "someString")
  1. Logger(来自iOS v14)-打印 32768符号也会打印到控制台。比以前有更好的表现
@import os
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "someCategory")
logger.log("\(s)")