it-swarm.com.de

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

Was ist der Unterschied zwischen print, NSLog und println und wann soll ich welche verwenden?

Wenn ich zum Beispiel in Python ein Wörterbuch drucken wollte, hätte ich nur print myDict, aber jetzt habe ich zwei andere Optionen. Wie und wann soll ich welche verwenden?

411
User

Ein paar Unterschiede:

  1. print vs println:

    Die Funktion print druckt beim Debuggen von Apps Meldungen in der Xcode-Konsole.

    Die println ist eine Variation davon, die in Swift 2 entfernt wurde und nicht mehr verwendet wird. Wenn Sie alten Code sehen, der println verwendet, können Sie ihn jetzt sicher durch print ersetzen.

    Zurück in Swift 1.x, print hat am Ende der gedruckten Zeichenfolge keine Zeilenumbrüche hinzugefügt, während println dies tat. Heutzutage fügt print immer das Zeilenumbruchzeichen am Ende der Zeichenfolge hinzu. Wenn Sie dies nicht möchten, geben Sie den terminator -Parameter "" an.

  2. NSLog:

    • NSLog ist langsamer;

    • NSLog fügt der Ausgabe einen Zeitstempel und einen Bezeichner hinzu, während print dies nicht tut;

    • NSLog -Anweisungen werden sowohl in der Gerätekonsole als auch in der Debugger-Konsole angezeigt, während print nur in der Debugger-Konsole angezeigt wird.

    • NSLog verwendet printf-Formatstrings, z.

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

      das wird produzieren:

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

  3. Ab iOS 10/macOS 10.12 gibt es eine dritte Alternative, os_log, die Teil des "Unified Logging" -Systems ist (siehe WWDC 2016-Video nified Logging and Activity Tracing ).

    • Sie müssen os.log importieren, bevor Sie die Funktion os_log verwenden können:

      import os.log
      
    • Wie NSLog gibt os_log Nachrichten sowohl an die Xcode-Debug-Konsole als auch an die Gerätekonsole aus

    • Sie können jetzt die in der Konsolen-App verfügbaren Felder "Subsystem" und "Kategorie" steuern. Zum Beispiel:

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

      Wenn Sie die App über die externe Konsolen-App beobachten, können Sie diese Spalten nicht nur zur Hauptansicht hinzufügen, sondern anhand dieser auch filtern. Dies ist sehr nützlich, wenn Sie Ihre Debugging-Meldungen von (a) Meldungen unterscheiden möchten, die von anderen Subsystemen im Auftrag Ihrer App generiert wurden. oder (b) Nachrichten aus anderen Kategorien oder Typen.

    • Sie können verschiedene Arten von Protokollmeldungen angeben, entweder .info, .debug, .error, .fault (oder .default):

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

      Wenn Sie also die externe Konsolen-App verwenden, können Sie festlegen, dass nur Nachrichten bestimmter Kategorien angezeigt werden (z. B. Debugging-Nachrichten nur anzeigen, wenn Sie im Menü "Aktion" der Konsole die Option "Debugging-Nachrichten einschließen" auswählen). Diese Einstellungen bestimmen auch viele Details darüber, ob Dinge auf der Festplatte protokolliert werden oder nicht. Weitere Informationen finden Sie im WWDC-Video.

    • Sie können die Zeichenfolgeninterpolation nicht verwenden, wenn Sie os_log verwenden. Zum Beispiel können Sie nicht tun:

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

      Sie müssten Folgendes tun:

      os_log("url = %@", url.absoluteString)
      
    • Einer der Gründe für die oben genannte Einschränkung ist die Unterstützung des Datenschutzes. Primitive Datentypen (z. B. Zahlen) sind standardmäßig öffentlich und Objekte (z. B. Zeichenfolgen) sind standardmäßig privat. Im vorherigen Beispiel, in dem Sie die URL protokolliert haben und die App vom Gerät selbst aufgerufen wurde und Sie über die Konsolen-App Ihres Macs zugesehen haben, wird Folgendes angezeigt:

      url = <privat>

      Wenn Sie es von einem externen Gerät aus sehen möchten, müssen Sie Folgendes tun:

      os_log("url = %{public}@", url.absoluteString)
      
    • Beachten Sie, dass NSLog jetzt das einheitliche Benachrichtigungssystem hinter den Kulissen verwendet, jedoch mit den folgenden Einschränkungen:

      • Sie können das Subsystem oder die Kategorie oder den Protokolltyp nicht steuern.

      • Es werden keine Datenschutzeinstellungen unterstützt.

Unterm Strich ist print für einfache Aufgaben ausreichend, aber NSLog ist nützlich, weil es Zeitstempelinformationen für Sie enthält.

Die Leistungsfähigkeit von os_log kommt beim Debuggen von iOS-Apps, die außerhalb von Xcode getestet werden müssen, deutlich zur Geltung. Wenn Sie beispielsweise iOS-App-Prozesse im Hintergrund testen, wie z. B. das Abrufen im Hintergrund, wird eine Verbindung zum Xcode-Debugger hergestellt ändert den Lebenszyklus der App . Daher möchten Sie häufig auf einem physischen Gerät testen, indem Sie die App auf dem Gerät selbst ausführen und die App nicht über den Xcode-Debugger starten. Mit der einheitlichen Protokollierung können Sie weiterhin die os_log -Anweisungen Ihres iOS-Geräts in der macOS Console-App anzeigen.

682
Rob

Wenn Sie Swift 2 verwenden, können Sie jetzt nur print () verwenden, um etwas in die Ausgabe zu schreiben.

Apple hat die beiden Funktionen println () und print () zu einer zusammengefasst.

Auf iOS 9 aktualisiert

Standardmäßig beendet die Funktion die gedruckte Zeile durch Hinzufügen eines Zeilenumbruchs.

print("Hello Swift")

Terminator

Übergeben Sie eine leere Zeichenfolge als Abschlusszeichen, um einen Wert ohne Zeilenumbruch zu drucken

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

Trennzeichen

Sie können jetzt Trennzeichen verwenden, um mehrere Elemente zu verketten

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

Beide

Oder Sie könnten auf diese Weise kombinieren

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

Darüber hinaus hat Swift 2 debugPrint() (und CustomDebugStringConvertible protocol)!

Vergessen Sie nicht debugPrint(), das wie print() funktioniert, aber am besten geeignet für Debugging .

Beispiele:

  • Strings
    • print("Hello World!") wird Hello World
    • debugPrint("Hello World!") wird "Hello World" (Anführungszeichen!)
  • Bereiche
    • print(1..<6) wird 1..<6
    • debugPrint(1..<6) wird Range(1..<6)

Jede Klasse kann ihre Debug-String-Darstellung über das Protokoll CustomDebugStringConvertible anpassen.

60

Als Ergänzung zu Robs Antwort hat Apple seit iOS 10.0 ein völlig neues "Unified Logging" -System eingeführt, das vorhandene Protokollierungssysteme (einschließlich ASL und Syslog, NSLog) ersetzt und die vorhandenen Protokollierungsansätze hinsichtlich der Leistung übertrifft. Dank seiner neuen Techniken, einschließlich Protokolldatenkomprimierung und verzögerter Datenerfassung.

Von Apple :

Das vereinheitlichte Protokollierungssystem bietet eine einzige, effiziente und leistungsfähige API für die Erfassung von Nachrichten auf allen Ebenen des Systems. Dieses einheitliche System zentralisiert die Speicherung von Protokolldaten im Speicher und in einem Datenspeicher auf der Festplatte.

Apple empfiehlt dringend, os_log zu verwenden, um künftig alle Arten von Nachrichten zu protokollieren, einschließlich Informationen, Fehlerbehebung und Fehlermeldungen, da die Leistung im Vergleich zu früheren Protokollierungssystemen erheblich verbessert wurde und die zentralisierte Datenerfassung eine bequeme Prüfung von Protokollen und Aktivitäten für Entwickler ermöglicht . Tatsächlich ist das neue System wahrscheinlich so platzsparend, dass es nicht den "Beobachter-Effekt" hervorruft, bei dem Ihr Fehler verschwindet, wenn Sie einen Protokollierungsbefehl einfügen, der das Timing des Fehlers beeinträchtigt.

Performance of Activity Tracing, now part of the new Unified Logging system

Mehr dazu erfahren Sie im Detail hier .

Um es zusammenzufassen: Verwenden Sie print() für Ihr persönliches Debugging (die Nachricht wird jedoch nicht protokolliert, wenn sie auf Benutzergeräten bereitgestellt wird). Verwenden Sie dann Unified Logging (os_log) so oft wie möglich für alles andere.

32
HuaTham

Es gibt eine andere Methode namens dump(), die auch für die Protokollierung verwendet werden kann:

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

Kopiert den Inhalt eines Objekts mithilfe seines Spiegels auf die Standardausgabe.

Von Swift Standard Library Functions

3
JAL