有什么区别print,我应该在什么时候使用它们?NSLog``println
print
NSLog``println
例如,在 Python 中,如果我想打印字典,我会print myDict选择 ,但现在我有 2 个其他选项。我应该如何以及何时使用每个?
print myDict
几个区别:
println
该print函数在调试应用程序时在 Xcode 控制台中打印消息。
这println是一个在 Swift 2 中被删除并且不再使用的变体。如果您看到正在使用的旧代码println,您现在可以安全地将其替换为print.
回到 Swift 1.x 中,print没有在打印字符串的末尾添加换行符,而println这样做了。但是现在,print总是在字符串末尾添加换行符,如果您不希望它这样做,请terminator提供"".
terminator
""
NSLog:
NSLog
NSLog在输出中添加时间戳和标识符,而print不会;
NSLog语句出现在设备的控制台和调试器的控制台中,而print仅出现在调试器控制台中。
NSLog在 iOS 10-13/macOS 10.12-10.x 中使用printf-style 格式字符串,例如
printf
NSLog("%0.4f", CGFloat.pi)
这将产生:
2017-06-09 11:57:55.642328-0700 MyApp[28937:1751492] 3.1416
* `NSLog`从 iOS 14/macOS 11 开始可以使用字符串插值。(然后,在 iOS 14 和 macOS 11 中,我们通常更倾向于`Logger`.`NSLog`见下一点。)
如今,虽然NSLog仍然有效,但我们通常会使用“统一日志记录”(见下文)而不是NSLog.
从 iOS 14/macOS 11 开始,我们有了Logger“统一日志”系统的接口。有关 的介绍Logger,请参阅 WWDC 2020探索使用 Swift 登录。
Logger
要使用Logger,您必须导入os:
os
import os
像NSLog,统一日志也会同时向 Xcode 调试控制台和设备控制台输出消息
创建一个Logger和log一个消息给它:
log
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
logger.log(“url = (url)”)
当您通过外部控制台应用程序观察应用程序时,您可以根据subsystem和进行过滤category。将调试消息与 (a) 其他子系统代表您的应用程序生成的消息或 (b) 来自其他类别或类型的消息区分开来是非常有用的。
subsystem
category
* 您可以指定不同类型的日志消息,包括`.info`、`.debug`、`.error`、`.fault`、`.critical`、`.notice`、`.trace`等: logger.error("web service did not respond \(error.localizedDescription)")
因此,如果使用外部控制台应用程序,您可以选择仅查看某些类别的消息(例如,如果您在控制台“操作”菜单上选择“包含调试消息”,则仅显示调试消息)。这些设置还规定了许多关于事物是否记录到磁盘的微妙问题细节。有关详细信息,请参阅 WWDC 视频。
* 默认情况下,非数字数据会在日志中进行编辑。在您记录 URL 的示例中,如果应用程序是从设备本身调用的,并且您正在从 macOS 控制台应用程序观看,您将在 macOS 控制台中看到以下内容:
网址 = <私人>
如果您确信此消息不会包含用户机密数据并且您希望在 macOS 控制台中查看字符串,则必须执行以下操作:
os_log("url = \(url, privacy: .public)")
在 iOS 14/macOS 11 之前,iOS 10/macOS 10.12 引入 os_log了“统一日志”。有关统一日志记录的一般介绍,请参阅 WWDC 2016 视频统一日志记录和活动跟踪。
os_log
进口os.log:
os.log
import os.log
您应该定义subsystemand category:
let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
使用时os_log,您将使用 printf 样式的模式而不是字符串插值:
os_log("url = %@", log: log, url.absoluteString) * 您可以指定不同类型的日志消息,无论是`.info`、`.debug`、`.error`、`.fault`(或`.default`): os_log("web service did not respond", type: .error) * 使用时不能使用字符串插值`os_log`。例如`print`,`Logger`你这样做: logger.log("url = \(url)")
但是os_log,你必须这样做:
os_log("url = %@", url.absoluteString) * 强制执行相同的`os_log`数据隐私,但您在 printf 格式化程序中指定公共可见性(例如`%{public}@`,而不是`%@`)。例如,如果您想从外部设备查看它,您必须这样做: os_log("url = %{public}@", url.absoluteString) * 如果您想观看 Instruments 的活动范围,还可以使用“兴趣点”日志: let pointsOfInterest = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: .pointsOfInterest)
并开始一个范围:
os_signpost(.begin, log: pointsOfInterest, name: "Network request")
并以以下方式结束:
os_signpost(.end, log: pointsOfInterest, name: "Network request")
有关更多信息,请参阅https://stackoverflow.com/a/39416673/1271826。
最重要的是,print对于使用 Xcode 进行简单的日志记录已经足够了,但是统一的日志记录(无论是Logger还是os_log)实现了同样的事情,但提供了更强大的功能。
当调试必须在 Xcode 之外进行测试的 iOS 应用程序时,统一日志记录的力量就显露出来。例如,在测试后台 iOS 应用程序进程(如后台获取)时,连接到 Xcode调试器会更改应用程序生命周期。因此,您经常需要在物理设备上进行测试,从设备本身运行应用程序,而不是从Xcode 的调试器启动应用程序。统一日志记录让您仍然可以从 macOS 控制台应用程序查看您的 iOS 设备日志语句。