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


450

Quelle est la différence entre print, NSLoget printlnquand dois - je utiliser chacun?

Par exemple, en Python, si je voulais imprimer un dictionnaire, je le ferais print myDict, mais maintenant j'ai 2 autres options. Comment et quand dois-je les utiliser?



2
Qu'en est-il de NSLog et l'impression d'un NSDictionary ne me donne rien d'utile?
Utilisateur

À partir d'iOS 10.0, il est recommandé de l'utiliser os_log. Veuillez voir ma réponse ci-dessous .
HuaTham

En plus de voir la documentation Swift sur os_log: essayez de voir la documentation complète de la page objective-C. C'est beaucoup plus complet .
Honey

Réponses:


758

Quelques différences:

  1. printvs println:

    La printfonction imprime des messages dans la console Xcode lors du débogage des applications.

    C'est printlnune variante de cela qui a été supprimée dans Swift 2 et qui n'est plus utilisée. Si vous voyez l'ancien code utilisé println, vous pouvez maintenant le remplacer en toute sécurité par print.

    De retour dans Swift 1.x, printn'a pas ajouté de caractères de nouvelle ligne à la fin de la chaîne imprimée, alors que printlnoui. Mais de nos jours, printajoute toujours le caractère de nouvelle ligne à la fin de la chaîne, et si vous ne le souhaitez pas, fournissez un terminatorparamètre de "".

  2. NSLog:

    • NSLog est plus lent;

    • NSLogajoute un horodatage et un identifiant à la sortie, alors que printnon;

    • NSLogLes instructions apparaissent à la fois dans la console du périphérique et dans la console du débogueur, alors printqu'elles n'apparaissent que dans la console du débogueur.

    • NSLogutilise printfdes chaînes de format -style, par exemple

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

      qui produira:

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

  3. À partir d'iOS 10 / macOS 10.12, il existe une troisième alternative, os_logfaisant partie du système de «journalisation unifiée» (voir la vidéo de la WWDC 2016 Journalisation unifiée et suivi des activités ).

    • Vous devez importer os.logavant d'utiliser la os_logfonction:

      import os.log
    • Comme NSLog, os_logaffichera des messages à la fois sur la console de débogage Xcode et la console de l'appareil

    • Vous pouvez désormais contrôler les champs "sous-système" et "catégorie" disponibles dans l'application Console. Par exemple:

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

      Lorsque vous observez l'application via l'application console externe, vous pouvez non seulement ajouter ces colonnes à la vue principale, mais vous pouvez filtrer en fonction de celles-ci. C'est très utile lorsque vous souhaitez différencier vos messages de débogage de (a) ceux générés par d'autres sous-systèmes au nom de votre application; ou (b) des messages d'autres catégories ou types.

    • Vous pouvez spécifier différents types de journalisation des messages, que ce soit .info, .debug, .error, .fault(ou .default):

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

      Ainsi, si vous utilisez l'application console externe, vous pouvez choisir de ne voir que les messages de certaines catégories (par exemple, afficher uniquement les messages de débogage si vous choisissez "Inclure les messages de débogage" dans le menu "Action" de la console). Ces paramètres dictent également de nombreux détails subtils sur la question de savoir si les choses sont enregistrées sur disque ou non. Voir la vidéo WWDC pour plus de détails.

    • Vous ne pouvez pas utiliser d'interpolation de chaîne lors de l'utilisation os_log. Par exemple, vous ne pouvez pas faire:

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

      Vous auriez à faire:

      os_log("url = %@", url.absoluteString)
    • L'une des raisons de la limitation ci-dessus est de prendre en charge la confidentialité des données. Les types de données primitifs (par exemple les nombres) sont publics par défaut et les objets (par exemple les chaînes) sont privés par défaut. Dans l'exemple précédent où vous avez enregistré l'URL, si l'application était invoquée depuis l'appareil lui-même et que vous regardiez depuis l'application de la console de votre Mac, vous verriez:

      url = <privé>

      Si vous vouliez le voir depuis un périphérique externe, vous auriez à faire:

      os_log("url = %{public}@", url.absoluteString)
    • Remarque, NSLogutilise désormais le système de notification unifié en arrière-plan, mais avec les mises en garde suivantes:

      • Vous ne pouvez pas contrôler le sous-système ou la catégorie ou le type de journal;

      • Il ne prend pas en charge les paramètres de confidentialité.

En bout de ligne, printest suffisant pour les tâches simples, mais NSLogest utile car il comprend des informations d'horodatage pour vous.

La puissance de os_logvient en relief lors du débogage des applications iOS qui doivent être testées en dehors de Xcode. Par exemple, lors du test de processus d'application iOS en arrière-plan, comme la récupération en arrière-plan, la connexion au débogueur Xcode modifie le cycle de vie de l'application . Ainsi, vous souhaiterez fréquemment tester sur un appareil physique, en exécutant l'application à partir de l'appareil lui-même, sans démarrer l'application à partir du débogueur de Xcode. La journalisation unifiée vous permet de toujours regarder les os_logrelevés de votre appareil iOS à partir de l'application console macOS.


37
Joli résumé! Pour en ajouter quelques autres: vous pouvez passer une NSString à println, mais pas NSLog; vous pouvez ajouter des arguments pour NSLog, mais pas println; L'interpolation de chaîne de style rapide se bloque parfois pour NSLog, mais pas println.
Bao Lei

2
une note intéressante sur l'optimisation du compilateur Swift et l'utilisation de print () medium.com/ios-os-x-development/…
Carl

@Rob si j'utilise print, apparaît-il ou non dans la console de débogage? Ou devrions-nous utiliser debugPrint?

1
Si vous utilisez print, il apparaît dans la zone de débogage de Xcode, tout comme debugPrint. La seule différence est que cela printfinit par appeler la descriptionméthode de l'objet et les debugPrintappels debugDescription, qui peuvent être plus verbeux que description.
Rob

@Honey, ce fil de commentaires a été signalé comme étant excessivement long, donc je voulais juste vous rappeler que les commentaires ne sont pas destinés à des sessions de discussion ou de débogage prolongées. Si vous avez quelque chose qui peut se poser comme une question qui convient pour le format Stack Overflow, alors s'il vous plaît demander une question afin que chacun puisse bénéficier de ses réponses. Si cela ne fonctionne pas comme une question, vous devrez prendre la discussion pour discuter. Réservez vos commentaires uniquement pour demander des éclaircissements ou faire des observations rapides.
Cody Gray

80

Si vous utilisez Swift 2 , vous ne pouvez désormais utiliser que print () pour écrire quelque chose dans la sortie.

Apple a combiné les fonctions println () et print () en une seule.

Mise à jour vers iOS 9

Par défaut, la fonction termine la ligne qu'elle imprime en ajoutant un saut de ligne.

print("Hello Swift")

Terminator

Pour imprimer une valeur sans un saut de ligne après, passez une chaîne vide comme terminateur

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

Séparateur

Vous pouvez maintenant utiliser le séparateur pour concaténer plusieurs éléments

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

Tous les deux

Ou vous pouvez combiner l'utilisation de cette manière

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

5
appendNewlinea une valeur par défaut detrue
Adam

1
Dans iOS (9.0), vous devez utiliser terminator : "", par exempleprint("...", terminator: "")
Khotu Nam

L'énoncé de votre première phrase est incorrect. NSLog () fonctionne toujours, même dans la dernière Swift 2.x
Sebastian

62

De plus, Swift 2 a debugPrint()(et CustomDebugStringConvertibleprotocole)!

N'oubliez pas debugPrint()ce qui fonctionne print()mais qui convient le mieux au débogage .

Exemples:

  • Cordes
    • print("Hello World!") devient Hello World
    • debugPrint("Hello World!")devient "Hello World"(Citations!)
  • Gammes
    • print(1..<6) devient 1..<6
    • debugPrint(1..<6) devient Range(1..<6)

Toute classe peut personnaliser sa représentation de chaîne de débogage via le CustomDebugStringConvertibleprotocole.


2
DebugPrintableprotocole a été renommé en CustomDebugStringConvertibleprotocole .
Franklin Yu

Merci, Franklin!
Valentin Shergin

Donc , Swift descriptionest debugDescriptionque Python strest de repr?
BallpointBen

Oui, je le pense.
Valentin Shergin

39

Pour ajouter à la réponse de Rob, depuis iOS 10.0, Apple a introduit un tout nouveau système de «journalisation unifiée» qui remplace les systèmes de journalisation existants (y compris ASL et Syslog, NSLog), et surpasse également les approches de journalisation existantes en termes de performances, grâce à ses nouvelles techniques, notamment compression des données de journal et collecte de données différée.

D' Apple :

Le système de journalisation unifiée fournit une API unique, efficace et performante pour capturer la messagerie à tous les niveaux du système. Ce système unifié centralise le stockage des données de journal en mémoire et dans un magasin de données sur disque.

Apple recommande vivement d'utiliser os_logà l'avenir pour enregistrer toutes sortes de messages, y compris les informations, le débogage, les messages d'erreur en raison de ses performances nettement améliorées par rapport aux systèmes de journalisation précédents et de sa collecte de données centralisée permettant une inspection pratique des journaux et des activités pour les développeurs. En fait, le nouveau système est probablement si peu encombrant qu'il ne provoquera pas «l'effet d'observateur» là où votre bogue disparaîtra si vous insérez une commande de journalisation, interférant ainsi avec le timing du bogue.

Performances du suivi des activités, désormais intégrées au nouveau système de journalisation unifiée

Vous pouvez en savoir plus à ce sujet dans les détails ici .

Pour résumer: utilisez print()pour votre débogage personnel pour plus de commodité (mais le message ne sera pas enregistré lors du déploiement sur les machines des utilisateurs). Ensuite, utilisez la journalisation unifiée ( os_log) autant que possible pour tout le reste.


5

Il existe une autre méthode appelée dump()qui peut également être utilisée pour la journalisation:

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

Vide le contenu d'un objet à l'aide de son miroir vers la sortie standard.

Depuis les fonctions de bibliothèque standard de Swift

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.