printNSLogprintln之间有什么区别?我应该在什么时候使用它们?

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

推荐答案

有几点不同:

  1. printprintln:

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

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

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

  2. NSLog:

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

    • NSLog条语句同时出现在设备控制台和调试器控制台中,而print条语句只出现在调试器控制台中.

    • NSLog在iOS 10-13/macOS 10.12-10中.x使用printf样式格式字符串,例如.

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

      这将产生:

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

    • 来自iOS 14/macOS 11的NSLog可以使用字符串插值.(同样,在iOS 14和macOS 11中,我们通常倾向于Logger而不是NSLog.请看下一点.)

    如今,虽然NSLog仍然有效,但我们通常使用"统一日志(log)"(见下文)而不是NSLog.

  3. 有效的iOS 14/macOS 11,我们有Logger个与"统一日志(log)"系统的接口.有关Logger的介绍,请参见WWDC 2020 Explore logging in Swift.

    • 要使用Logger,必须导入os:

      import os
      
    • NSLog一样,统一日志(log)也将向Xcode调试控制台和设备控制台输出消息

    • 创建一个Logger并向其发送消息:

      let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "network")
      logger.log("url = \(url)")
      

      通过外部控制台应用程序观察应用程序时,可以根据subsystemcategory进行过滤.区分调试消息与(a)其他子系统代表应用程序生成的消息,或(b)其他类别或类型的消息非常有用.

    • 您可以指定不同类型的日志(log)消息,如.info.debug.error.fault.critical.notice.trace等:

      logger.error("web service did not respond \(error.localizedDescription)")
      

      因此,如果使用外部控制台应用程序,您可以 Select 仅查看特定类别的消息(例如,如果在控制台"操作"菜单上 Select "包括调试消息",则仅显示调试消息).这些设置还决定了许多微妙的问题,比如是否将内容记录到磁盘.有关更多详细信息,请参阅WWDC视频.

    • 默认情况下,非数字数据会在日志(log)中进行编辑.在您记录URL的示例中,如果应用程序是从设备本身调用的,并且您是从macOS控制台应用程序观看的,您将在macOS控制台中看到以下内容:

      url=<;私有>;

      如果您确信此消息不会包含用户机密数据,并且希望在macOS控制台中看到字符串,则必须执行以下操作:

      os_log("url = \(url, privacy: .public)")
      
  4. 在iOS 14/macOS 11之前,iOS 10/macOS 10.12引入了用于"统一日志(log)"的os_log.有关统一日志(log)的一般介绍,请参阅WWDC 2016 video Unified Logging and Activity Tracing.

    • 进口os.log:

      import os.log
      
    • 您应该定义subsystemcategory:

      let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "network")
      

      使用os_log时,您将使用printf样式的图案,而不是字符串插值:

      os_log("url = %@", log: log, url.absoluteString)
      
    • 您可以指定不同类型的日志(log)消息,.info.debug.error.fault(或.default):

      os_log("web service did not respond", type: .error)
      
    • 使用os_log时不能使用字符串插值.例如,对于printLogger,您可以:

      logger.log("url = \(url)")
      

      但是有了os_log,你必须:

      os_log("url = %@", url.absoluteString)
      
    • os_log强制执行相同的数据隐私,但在printf格式化程序中指定公共可见性(例如%{public}@而不是%@).例如,如果你想从外部设备上看到它,你必须:

      os_log("url = %{public}@", url.absoluteString)
      
    • 如果您想从仪器上观看各种活动,也可以使用"兴趣点"日志(log):

      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的简单日志(log)记录来说已经足够了,但是统一日志(log)记录(不管是Logger还是os_log)实现了同样的功能,但提供了更大的功能.

当调试必须在Xcode之外测试的iOS应用程序时,统一日志(log)记录的威力得到了极大的释放.例如,在测试后台iOS应用程序进程(如后台获取)时,连接到Xcode调试器changes the app lifecycle.因此,您经常需要在物理设备上进行测试,从设备本身运行应用程序,而不是从Xcode的调试器启动应用程序.通过统一日志(log)记录,您仍然可以在macOS控制台应用程序中查看iOS设备日志(log)语句.

Swift相关问答推荐

SwiftUI—如何识别单词并获取视觉中的位置

ARRaycast Query和前置摄像头(ARFaceTrackingConfiguration)

当TextField变为空时,不会触发onChange

在SWIFT中使用Objective-C struct 时出错(在作用域中找不到类型)

MacOS 13-如何使用SwiftUI创建Message.App设置工具栏?

文件命名&NumberForMatter+扩展名&:含义?

允许视图在视图内更改

在SwiftUI中使用ForEach循环来显示字典项的键和值在Form视图中

使用异步收集发布者值

swiftui中服务端图片如何设计view并赋予rotationEffect?

LeetCode 249. 分组移位字符串

如何更改 Picker 的边框 colored颜色

找不到目标AAA的 SPM 工件 - 仅限 Xcode 13.3

如何快速判断设备方向是横向还是横向?

使用 Alamofire 4.0 (Swift 3) 下载文件

在 Swift for iOS 中沿圆形路径绘制文本

Swift 3:小数到 Int

在 Swift 中子类化 NSObject - 初始化器的最佳实践

如何在 SwiftUI 中的一个视图上显示两个alert ?

如何将应用程序与 iOS 联系人应用程序集成?