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

450

Jaka jest różnica między print, NSLogi printlnkiedy należy używać każdego?

Na przykład w Pythonie, gdybym chciał wydrukować słownik, chciałbym tylko print myDict, ale teraz mam 2 inne opcje. Jak i kiedy powinienem używać każdego z nich?

Użytkownik
źródło
1
możliwy duplikat różnicy między println a print w Swift
Connor,
2
co z NSLog i wydrukowaniem NSDictionary nic mi nie da?
Użytkownik
Od wersji iOS 10.0 zaleca się korzystanie z niej os_log. Zobacz moją odpowiedź poniżej .
HuaTham,
Oprócz przeglądania dokumentacji Swift na os_log: spróbuj zobaczyć pełną dokumentację strony C celu. Jest o wiele bardziej kompletny .
Kochanie,

Odpowiedzi:

758

Kilka różnic:

  1. printvs println:

    Do printwiadomości druki funkcyjne w konsoli Xcode podczas debugowania aplikacji.

    printlnJest odmianą tego, który został usunięty w Swift 2 i nie jest stosowane. Jeśli widzisz stary używany kod println, możesz go teraz bezpiecznie zastąpić print.

    W wersji Swift 1.x printnie dodawano znaków nowego wiersza na końcu drukowanego ciągu, a printlnzrobiono to. Ale w dzisiejszych czasach printzawsze dodaje znak nowej linii na końcu łańcucha, a jeśli nie chcesz tego robić, podaj terminatorparametr "".

  2. NSLog:

    • NSLog jest wolniejszy;

    • NSLogdodaje znacznik czasu i identyfikator do wyniku, natomiast printnie;

    • NSLoginstrukcje pojawiają się zarówno w konsoli urządzenia, jak i konsoli debuggera, podczas gdy printpojawiają się tylko w konsoli debuggera.

    • NSLogużywa printfciągów formatu -styl, np

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

      które wytworzą:

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

  3. W systemie iOS 10 / macOS 10.12 istnieje trzecia alternatywa, os_logczęść systemu „ujednoliconego rejestrowania” (patrz wideo Ujednolicone rejestrowanie i śledzenie aktywności WWDC 2016 ).

    • Musisz zaimportować os.logprzed użyciem os_logfunkcji:

      import os.log
    • Podobnie NSLog, os_logwyświetli komunikaty zarówno do konsoli debugowania Xcode, jak i konsoli urządzenia

    • Możesz teraz kontrolować pola „podsystem” i „kategoria” dostępne w aplikacji konsoli. Na przykład:

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

      Gdy obserwujesz aplikację za pomocą zewnętrznej aplikacji konsoli, możesz nie tylko dodać te kolumny do głównego widoku, ale możesz je filtrować na ich podstawie. Jest to bardzo przydatne, gdy chcesz odróżnić wiadomości debugowania od (a) wiadomości generowanych przez inne podsystemy w imieniu Twojej aplikacji; lub (b) wiadomości z innych kategorii lub typów.

    • Można określić różne typy rejestrowania komunikatów, albo .info, .debug, .error, .fault(a .default):

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

      Tak więc, jeśli używasz zewnętrznej aplikacji konsoli, możesz wyświetlać tylko wiadomości niektórych kategorii (np. Pokazywać wiadomości debugowania tylko, jeśli wybierzesz „Uwzględnij komunikaty debugowania” w menu „Akcja” konsoli). Te ustawienia dyktują również wiele subtelnych problemów dotyczących tego, czy rzeczy są zapisywane na dysku, czy nie. Zobacz wideo WWDC, aby uzyskać więcej informacji.

    • Podczas używania nie można używać interpolacji ciągów os_log. Na przykład nie możesz zrobić:

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

      Musisz zrobić:

      os_log("url = %@", url.absoluteString)
    • Jednym z powodów powyższego ograniczenia jest wspieranie prywatności danych. Pierwotne typy danych (np. Liczby) są domyślnie publiczne, a obiekty (np. Łańcuchy) są domyślnie prywatne. W poprzednim przykładzie, w którym zarejestrowałeś adres URL, jeśli aplikacja została wywołana z samego urządzenia i oglądałeś z aplikacji konsoli Maca, zobaczysz:

      url = <prywatne>

      Jeśli chcesz zobaczyć to z urządzenia zewnętrznego, musisz zrobić:

      os_log("url = %{public}@", url.absoluteString)
    • Uwaga: NSLogteraz używa ujednoliconego systemu powiadomień za kulisami, ale z następującymi zastrzeżeniami:

      • Nie można kontrolować podsystemu, kategorii lub typu dziennika;

      • Nie obsługuje ustawień prywatności.

Podsumowując, printwystarcza do prostych zadań, ale NSLogjest użyteczny, ponieważ zawiera informacje o znacznikach czasu.

Moc os_logdebiutu w aplikacjach na iOS, które muszą być testowane poza Xcode, jest ogromna. Na przykład podczas testowania procesów aplikacji iOS w tle, takich jak pobieranie w tle, połączenie z debuggerem Xcode zmienia cykl życia aplikacji . Tak więc często będziesz chciał przetestować na urządzeniu fizycznym, uruchamiając aplikację z samego urządzenia, a nie uruchamiając aplikację z debugera Xcode. Ujednolicone rejestrowanie pozwala nadal oglądać os_logwyciągi z urządzenia z iOS w aplikacji MacOS Console.

Obrabować
źródło
37
Ładne podsumowanie! Aby dodać jeszcze kilka: możesz przekazać NSString do println, ale nie NSLog; możesz dodawać argumenty dla NSLog, ale nie println; Szybka interpolacja ciągów znaków czasami zawiesza się dla NSLog, ale nie println.
Bao Lei,
2
interesująca uwaga na temat optymalizacji kompilatora Swift i korzystania z print () medium.com/ios-os-x-development/…
Carl
@ Rob, jeśli korzystam z print, to czy pojawia się w konsoli debugowania, czy nie? Czy powinniśmy używać debugPrint?
1
Jeśli używasz print, pokazuje się w obszarze debugowania Xcode, podobnie jak debugPrint. Jedyną różnicą jest to, że printkończy się descriptionmetoda wywołania obiektu i debugPrintwywołań debugDescription, które mogą być bardziej szczegółowe niż description.
Rob
@ Kochanie, ten wątek komentarza został oznaczony jako zbyt długi, więc chciałem tylko przypomnieć, że komentarze nie są przeznaczone do długich dyskusji lub sesji debugowania. Jeśli masz coś, co może zostać poproszony jako pytanie, który jest odpowiedni dla formatu przepełnienie stosu, następnie należy poprosić go jako pytanie tak, że każdy może korzystać z jego odpowiedzi. Jeśli to nie działa jako pytanie, musisz porozmawiać na czacie. Zarezerwuj komentarze tylko po to, by poprosić o wyjaśnienia lub dokonać szybkich obserwacji.
Cody Gray
80

Jeśli używasz Swift 2 , teraz możesz tylko print () zapisać coś na wyjściu.

Apple połączył funkcje println () i print () w jedną.

Zaktualizowano do iOS 9

Domyślnie funkcja kończy linię, którą drukuje, dodając podział linii.

print("Hello Swift")

Terminator

Aby wydrukować wartość bez podziału wiersza po niej, podaj pusty ciąg jako terminator

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

Separator

Możesz teraz używać separatora do łączenia wielu elementów

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

Obie

Lub możesz połączyć używając w ten sposób

print("Hello", "Swift", 2, separator:" ", terminator:".")
Jorge Casariego
źródło
5
appendNewlinema wartość domyślnątrue
Adam
1
W iOS (9.0) musisz użyć terminator : "", np.print("...", terminator: "")
Khotu Nam
Oświadczenie w pierwszym zdaniu jest niepoprawne. NSLog () nadal działa, nawet w najnowszym Swift 2.x
Sebastian
62

Co więcej, Swift 2 ma debugPrint()(i CustomDebugStringConvertibleprotokół)!

Nie zapomnij o tym, debugPrint()który działa, print()ale najlepiej nadaje się do debugowania .

Przykłady:

  • Smyczki
    • print("Hello World!") staje się Hello World
    • debugPrint("Hello World!")staje się "Hello World"(Cytaty!)
  • Zakresy
    • print(1..<6) staje się 1..<6
    • debugPrint(1..<6) staje się Range(1..<6)

Każda klasa może dostosować swoją reprezentację ciągu debugowania za pomocą CustomDebugStringConvertibleprotokołu.

Valentin Shergin
źródło
2
DebugPrintablenazwa CustomDebugStringConvertibleprotokołu została zmieniona na protokół .
Franklin Yu
Dziękuję Franklin!
Valentin Shergin
Więc Swift descriptionjest debugDescriptionjak Pythona strjest repr?
BallpointBen
Tak myślę.
Valentin Shergin
39

Aby dodać do odpowiedzi Roba, od iOS 10.0 Apple wprowadził zupełnie nowy system „Unified Logging”, który zastępuje istniejące systemy rejestrowania (w tym ASL i Syslog, NSLog), a także przewyższa istniejące metody rejestrowania wydajności, dzięki nowym technikom, w tym kompresja danych dziennika i odroczone zbieranie danych.

Z Apple :

Zunifikowany system rejestrowania zapewnia jeden, wydajny i wydajny interfejs API do przechwytywania komunikatów na wszystkich poziomach systemu. Ten zunifikowany system centralizuje przechowywanie danych dziennika w pamięci i magazynie danych na dysku.

Firma Apple zdecydowanie zaleca korzystanie os_logz rejestrowania wszelkiego rodzaju wiadomości, w tym informacji, debugowania i komunikatów o błędach, ze względu na znacznie lepszą wydajność w porównaniu do poprzednich systemów rejestrowania oraz scentralizowane gromadzenie danych, które umożliwia programistom wygodne sprawdzanie dzienników i aktywności. W rzeczywistości nowy system prawdopodobnie ma tak mało miejsca, że ​​nie spowoduje „efektu obserwatora”, w którym twój błąd zniknie, jeśli wstawisz komendę rejestrowania, zakłócając czas wystąpienia błędu.

Wydajność śledzenia aktywności, teraz stanowiąca część nowego systemu Unified Logging

Więcej informacji na ten temat można znaleźć tutaj .

Podsumowując: użyj print()do osobistego debugowania dla wygody (ale wiadomość nie zostanie zarejestrowana po wdrożeniu na urządzeniach użytkowników). Następnie użyj Unified Logging ( os_log) jak najwięcej do wszystkiego innego.

HuaTham
źródło
5

Istnieje inna metoda, dump()której można również użyć do logowania:

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

Zrzuca zawartość obiektu za pomocą lustra na standardowe wyjście.

Od standardowych funkcji biblioteki Swift

JAL
źródło