Swift: in () so với println () so với NSLog ()


450

Sự khác biệt giữa những gì print, NSLogprintlnkhi tôi nên sử dụng mỗi?

Ví dụ: trong Python nếu tôi muốn in một từ điển, tôi chỉ print myDict, nhưng bây giờ tôi có 2 tùy chọn khác. Làm thế nào và khi nào tôi nên sử dụng mỗi?



2
Điều gì về NSLog và in một NSDipedia không mang lại cho tôi bất cứ điều gì hữu ích?
Người dùng

Từ iOS 10.0 trở đi, chúng tôi khuyên bạn nên sử dụng os_log. Xin vui lòng xem câu trả lời của tôi dưới đây .
HuaTham

Ngoài việc xem tài liệu Swift trên os_log: hãy thử xem tài liệu đầy đủ của trang object-C. Nó hoàn thiện hơn nhiều .
Mật ong

Câu trả lời:


758

Một vài điểm khác biệt:

  1. printvs println:

    Các printthông điệp chức năng in trong Xcode console khi gỡ lỗi ứng dụng.

    Đây printlnlà một biến thể của cái này đã bị xóa trong Swift 2 và không còn được sử dụng nữa. Nếu bạn thấy mã cũ đang sử dụng println, bây giờ bạn có thể thay thế nó một cách an toàn print.

    Quay lại Swift 1.x, printđã không thêm các ký tự dòng mới vào cuối chuỗi in, trong khi đó printlnđã làm. Nhưng ngày nay, printluôn luôn thêm ký tự dòng mới ở cuối chuỗi và nếu bạn không muốn nó làm điều đó, hãy cung cấp một terminatortham số "".

  2. NSLog:

    • NSLog chậm hơn;

    • NSLogthêm dấu thời gian và mã định danh vào đầu ra, trong khi printsẽ không;

    • NSLogcâu lệnh xuất hiện trong cả bảng điều khiển của thiết bị và bảng điều khiển của trình gỡ lỗi trong khi printchỉ xuất hiện trong bảng điều khiển trình gỡ lỗi.

    • NSLogsử dụng printfchuỗi định dạng kiểu, ví dụ

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

      điều đó sẽ tạo ra:

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

  3. IOS 10 / macOS 10.12 hiệu quả, có một giải pháp thay thế thứ ba os_log, một phần của hệ thống "ghi nhật ký hợp nhất" (xem video Nhật ký hợp nhất và theo dõi hoạt động của WWDC 2016 ).

    • Bạn phải nhập os.logtrước khi sử dụng os_logchức năng:

      import os.log
    • Giống như NSLog, os_logcũng sẽ xuất thông báo cho cả bảng điều khiển gỡ lỗi Xcode và bảng điều khiển thiết bị.

    • Bây giờ bạn có thể kiểm soát các trường "hệ thống con" và "danh mục" có sẵn trong ứng dụng Bảng điều khiển. Ví dụ:

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

      Khi bạn quan sát ứng dụng thông qua ứng dụng Bảng điều khiển bên ngoài, bạn không chỉ có thể thêm các cột này vào chế độ xem chính mà còn có thể lọc dựa trên các cột này. Nó rất hữu ích khi muốn phân biệt các thông báo gỡ lỗi của bạn với (a) những thông báo được tạo bởi các hệ thống con khác thay mặt cho ứng dụng của bạn; hoặc (b) tin nhắn từ các danh mục hoặc loại khác.

    • Bạn có thể chỉ định các loại khác nhau của việc ghi lại các thông điệp, một trong hai .info, .debug, .error, .fault(hoặc .default):

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

      Vì vậy, nếu sử dụng ứng dụng Bảng điều khiển bên ngoài, bạn có thể chọn chỉ xem các tin nhắn thuộc một số danh mục nhất định (ví dụ: chỉ hiển thị các thông báo gỡ lỗi nếu bạn chọn "Bao gồm các thông báo gỡ lỗi" trên menu "Hành động" của Bảng điều khiển). Các cài đặt này cũng chỉ ra nhiều vấn đề tinh tế chi tiết về việc mọi thứ có được ghi vào đĩa hay không. Xem video WWDC để biết thêm chi tiết.

    • Bạn không thể sử dụng phép nội suy chuỗi khi sử dụng os_log. Ví dụ bạn không thể làm:

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

      Bạn sẽ phải làm:

      os_log("url = %@", url.absoluteString)
    • Một trong những lý do cho giới hạn trên là để hỗ trợ quyền riêng tư dữ liệu. Các kiểu dữ liệu nguyên thủy (ví dụ số) được công khai theo mặc định và các đối tượng (ví dụ: chuỗi) là riêng tư theo mặc định. Trong ví dụ trước nơi bạn đã đăng nhập URL, nếu ứng dụng được gọi từ chính thiết bị và bạn đang xem từ ứng dụng Console của Mac, bạn sẽ thấy:

      url = <riêng tư>

      Nếu bạn muốn xem nó từ thiết bị bên ngoài, bạn phải làm:

      os_log("url = %{public}@", url.absoluteString)
    • Lưu ý, NSLoghiện sử dụng hệ thống thông báo hợp nhất đằng sau hậu trường, nhưng với những cảnh báo sau:

      • Bạn không thể kiểm soát hệ thống con hoặc danh mục hoặc loại nhật ký;

      • Nó không hỗ trợ cài đặt quyền riêng tư.

Dòng dưới cùng, printlà đủ cho các nhiệm vụ đơn giản, nhưng NSLogrất hữu ích vì nó bao gồm thông tin dấu thời gian cho bạn.

Sức mạnh của os_logsự giảm bớt rõ rệt khi gỡ lỗi các ứng dụng iOS phải được thử nghiệm bên ngoài Xcode. Ví dụ: khi kiểm tra các quy trình ứng dụng iOS nền như tìm nạp nền, việc được kết nối với trình gỡ lỗi Xcode sẽ thay đổi vòng đời của ứng dụng . Vì vậy, bạn thường xuyên muốn kiểm tra trên thiết bị vật lý, chạy ứng dụng từ chính thiết bị, không khởi động ứng dụng từ trình gỡ lỗi của Xcode. Ghi nhật ký hợp nhất cho phép bạn vẫn xem các os_logtuyên bố về thiết bị iOS của mình từ ứng dụng Bảng điều khiển macOS.


37
Tóm tắt tốt đẹp! Để thêm một vài chi tiết: bạn có thể chuyển NSString sang println, nhưng không phải NSLog; bạn có thể thêm args cho NSLog, nhưng không println; Nội suy chuỗi kiểu Swift đôi khi gặp sự cố cho NSLog, nhưng không phải là println.
Bảo Lôi

2
một lưu ý thú vị về tối ưu hóa trình biên dịch Swift và việc sử dụng print () Medium.com/ios-os-x-development/ mẹo
Carl

@Rob nếu tôi sử dụng print thì nó có xuất hiện trong bảng điều khiển gỡ lỗi hay không? Hay chúng ta nên sử dụng debugPrint?

1
Nếu bạn sử dụng print, nó sẽ hiển thị trong vùng gỡ lỗi của Xcode, giống như debugPrint. Sự khác biệt duy nhất là printkết thúc descriptionphương thức gọi của đối tượng và debugPrintcác cuộc gọi debugDescription, có thể dài dòng hơn description.
Rob

@Honey, chủ đề bình luận này đã được gắn cờ là quá dài, vì vậy tôi chỉ muốn nhắc nhở bạn rằng các bình luận không dành cho các phiên thảo luận mở rộng hoặc gỡ lỗi. Nếu bạn có câu hỏi nào đó có thể được hỏi dưới dạng câu hỏi phù hợp với định dạng Stack Overflow, thì vui lòng hỏi nó dưới dạng câu hỏi để mọi người có thể hưởng lợi từ câu trả lời của nó. Nếu nó không hoạt động như một câu hỏi, thì bạn sẽ cần phải thảo luận để trò chuyện. Dự trữ ý kiến ​​chỉ để yêu cầu làm rõ hoặc quan sát nhanh.
Cody Grey

80

Nếu bạn đang sử dụng Swift 2 , bây giờ bạn chỉ có thể sử dụng print () để ghi một cái gì đó vào đầu ra.

Apple đã kết hợp cả hai hàm println ()print () thành một.

Đã cập nhật lên iOS 9

Theo mặc định, hàm chấm dứt dòng nó in bằng cách thêm ngắt dòng.

print("Hello Swift")

Kẻ hủy diệt

Để in một giá trị mà không ngắt dòng sau nó, hãy chuyển một chuỗi trống làm dấu kết thúc

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

Dấu phân cách

Bây giờ bạn có thể sử dụng dấu phân cách để ghép nhiều mục

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

Cả hai

Hoặc bạn có thể kết hợp sử dụng theo cách này

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

5
appendNewlinecó giá trị mặc định làtrue
Adam

1
Trong iOS (9.0), bạn cần phải sử dụng terminator : "", ví dụ nhưprint("...", terminator: "")
Khotu Nam

Các tuyên bố trong câu đầu tiên của bạn là không chính xác. NSLog () vẫn hoạt động, ngay cả trong Swift 2.x mới nhất
Sebastian

62

Hơn nữa, Swift 2 có debugPrint()(và CustomDebugStringConvertiblegiao thức)!

Đừng quên những gì debugPrint()hoạt động như thế nào print()nhưng phù hợp nhất để gỡ lỗi .

Ví dụ:

  • Dây
    • print("Hello World!") trở thành Hello World
    • debugPrint("Hello World!")trở thành "Hello World"(Báo giá!)
  • Các dãy
    • print(1..<6) trở thành 1..<6
    • debugPrint(1..<6) trở thành Range(1..<6)

Bất kỳ lớp nào cũng có thể tùy chỉnh biểu diễn chuỗi gỡ lỗi của chúng thông qua CustomDebugStringConvertiblegiao thức.


2
DebugPrintablegiao thức đã được đổi tên thành CustomDebugStringConvertiblegiao thức .
Franklin Yu

Cảm ơn, Franklin!
Valentin Shergin

Vì vậy, Swift descriptiondebugDescriptionnhư Python strlà để repr?
BallpointBen

Vâng tôi cũng nghĩ thế.
Valentin Shergin

39

Để thêm vào câu trả lời của Rob, kể từ iOS 10.0, Apple đã giới thiệu một hệ thống "Ghi nhật ký hợp nhất" hoàn toàn mới thay thế các hệ thống ghi nhật ký hiện có (bao gồm ASL và Syslog, NSLog) và cũng vượt qua các phương pháp ghi nhật ký hiện có về hiệu suất, nhờ các kỹ thuật mới bao gồm ghi dữ liệu nén và thu thập dữ liệu hoãn lại.

Từ Apple :

Hệ thống ghi nhật ký hợp nhất cung cấp một API hiệu suất, hiệu quả để ghi lại tin nhắn trên tất cả các cấp của hệ thống. Hệ thống hợp nhất này tập trung vào việc lưu trữ dữ liệu nhật ký trong bộ nhớ và trong kho lưu trữ dữ liệu trên đĩa.

Apple khuyên bạn nên sử dụng os_logchuyển tiếp để ghi nhật ký tất cả các loại thông báo, bao gồm thông tin, gỡ lỗi, thông báo lỗi vì hiệu suất được cải thiện hơn nhiều so với các hệ thống ghi nhật ký trước đó và bộ sưu tập dữ liệu tập trung cho phép kiểm tra nhật ký và hoạt động thuận tiện cho nhà phát triển. Trên thực tế, hệ thống mới có khả năng rất thấp đến nỗi nó sẽ không gây ra "hiệu ứng người quan sát" khi lỗi của bạn biến mất nếu bạn chèn lệnh ghi nhật ký, cản trở thời gian xảy ra lỗi.

Hiệu suất của Truy tìm hoạt động, hiện là một phần của hệ thống Ghi nhật ký hợp nhất mới

Bạn có thể tìm hiểu thêm về điều này chi tiết ở đây .

Để tổng hợp: sử dụng print()để gỡ lỗi cá nhân của bạn cho thuận tiện (nhưng thông báo sẽ không được ghi lại khi triển khai trên thiết bị người dùng). Sau đó, sử dụng Unified Logging ( os_log) càng nhiều càng tốt cho mọi thứ khác.


5

Có một phương pháp khác được gọi là dump()cũng có thể được sử dụng để ghi nhật ký:

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

Kết xuất nội dung của một đối tượng bằng cách sử dụng gương của nó để xuất ra tiêu chuẩn.

Từ chức năng thư viện tiêu chuẩn Swift

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.