Answers:
一些区别:
print
vs println
:
print
调试应用程序时,该函数在Xcode控制台中打印消息。
这println
是Swift 2中已删除且不再使用的变体。如果看到正在使用的旧代码,则println
现在可以安全地将其替换为print
。
回到Swift 1.x,print
没有在打印字符串的末尾添加换行符,而是添加了换行符println
。但如今,请print
始终在字符串的末尾添加换行符,如果您不希望这样做,请提供terminator
参数""
。
NSLog
:
NSLog
更慢
NSLog
在输出中添加时间戳和标识符,而print
不会;
NSLog
语句同时出现在设备的控制台和调试器的控制台中,而print
仅出现在调试器的控制台中。
NSLog
使用printf
-style格式的字符串,例如
NSLog("%0.4f", CGFloat.pi)
会产生:
2017-06-09 11:57:55.642328-0700 MyApp [28937:1751492] 3.1416
对于有效的iOS 10 / macOS 10.12,还有第三种选择,os_log
即“统一日志记录”系统的一部分(请参阅WWDC 2016视频统一日志记录和活动跟踪)。
您必须先导入,os.log
然后才能使用os_log
函数:
import os.log
像一样NSLog
,os_log
也会将消息输出到Xcode调试控制台和设备控制台。
现在,您可以控制控制台应用程序中可用的“子系统”和“类别”字段。例如:
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)
因此,如果使用外部控制台应用程序,则可以选择仅查看某些类别的消息(例如,如果在控制台的“操作”菜单上选择“包括调试消息”,则仅显示调试消息)。这些设置还规定了有关是否将内容记录到磁盘的许多细微问题的详细信息。有关更多详细信息,请参阅WWDC视频。
使用时不能使用字符串插值os_log
。例如,您不能执行以下操作:
os_log("foo \(url.absoluteString)")
您将必须执行以下操作:
os_log("url = %@", url.absoluteString)
上述限制的原因之一是为了支持数据隐私。默认情况下,原始数据类型(例如,数字)是公共的,而对象(例如,字符串)在默认情况下是私有的。在记录URL的上一个示例中,如果从设备本身调用了该应用程序,并且正在从Mac的Console应用程序观看,则将看到:
url = <私人>
如果要从外部设备查看它,则必须执行以下操作:
os_log("url = %{public}@", url.absoluteString)
注意,NSLog
现在在幕后使用统一通知系统,但有以下警告:
您无法控制子系统,类别或日志类型;
它不支持隐私设置。
底线print
足以完成简单的任务,但NSLog
很有用,因为它包含了您的时间戳信息。
的功率os_log
调试具有的Xcode以外的地方进行测试iOS应用程序,当进入鲜明的救济。例如,当测试后台iOS应用程序进程(例如后台获取)时,连接到Xcode调试器会更改应用程序生命周期。因此,您经常需要在物理设备上进行测试,而不是从Xcode的调试器启动应用程序,而是从设备本身运行应用程序。统一日志记录使您仍然可以os_log
从macOS控制台应用程序观看iOS设备语句。
print
,它将显示在Xcode的调试区域中,就像debugPrint
。唯一的区别是print
最终导致description
了对象的调用方法和debugPrint
调用debugDescription
,这可能比更加冗长description
。
如果您使用的是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:".")
appendNewline
的默认值为true
terminator : ""
,例如print("...", terminator: "")
debugPrint()
(和CustomDebugStringConvertible
协议)!不要忘了debugPrint()
其工作方式print()
,但最适合的调试。
例子:
print("Hello World!")
变成 Hello World
debugPrint("Hello World!")
成为"Hello World"
(行情!)print(1..<6)
变成 1..<6
debugPrint(1..<6)
变成 Range(1..<6)
任何类都可以通过CustomDebugStringConvertible
协议自定义其调试字符串表示形式。
DebugPrintable
protocol已重命名为CustomDebugStringConvertible
protocol。
description
是debugDescription
为Python的str
是repr
?
为了补充Rob的答案,自iOS 10.0起,Apple引入了一种全新的“统一日志记录”系统,该系统取代了现有的日志记录系统(包括ASL和Syslog,NSLog),并且由于其新技术,其性能也超过了现有的日志记录方法。日志数据压缩和延迟数据收集。
从苹果:
统一日志记录系统提供了一个单一,高效,高性能的API,用于捕获系统所有级别的消息。该统一系统集中了日志数据在内存中和磁盘上的数据存储中的存储。
Apple强烈建议使用os_log
向前记录各种消息,包括信息,调试,错误消息,因为与以前的记录系统相比,它的性能大大提高,并且其集中的数据收集功能为开发人员提供了方便的日志和活动检查。实际上,新系统的占用空间可能很小,因此如果您插入日志记录命令,不会导致臭虫消失的“观察者效应”,从而干扰了臭虫发生的时间。
您可以在此处详细了解更多信息。
总结一下:print()
为方便您的个人调试(但是在用户设备上部署时不会记录该消息)。然后,os_log
对于其他所有内容,请尽可能使用统一日志记录()。
还有一种称为的方法dump()
,也可以用于记录日志:
func dump<T>(T, name: String?, indent: Int, maxDepth: Int, maxItems: Int)
使用其镜像将对象的内容转储到标准输出。