On m'a dit cela à quelques reprises sur ce site même, mais je voulais m'assurer que c'était vraiment le cas.
Je m'attendais à pouvoir saupoudrer les appels de fonction NSLog dans tout mon code, et que Xcode / gcc supprimerait automatiquement ces appels lors de la construction de mes versions Release / Distribution.
Dois-je éviter de l'utiliser? Si oui, quelles alternatives sont les plus courantes entre les programmeurs Objective-C expérimentés?
Réponses:
Les macros de préprocesseur sont en effet parfaites pour le débogage. Il n'y a rien de mal avec NSLog (), mais il est simple de définir votre propre fonction de journalisation avec de meilleures fonctionnalités. Voici celui que j'utilise, il comprend le nom du fichier et le numéro de ligne pour faciliter le suivi des instructions de journal.
J'ai trouvé plus facile de mettre toute cette déclaration dans l'en-tête du préfixe plutôt que dans son propre fichier. Vous pouvez, si vous le souhaitez, créer un système de journalisation plus complexe en faisant interagir DebugLog avec des objets Objective-C normaux. Par exemple, vous pouvez avoir une classe de journalisation qui écrit dans son propre fichier journal (ou base de données), et inclut un argument `` priorité '' que vous pouvez définir au moment de l'exécution, de sorte que les messages de débogage ne sont pas affichés dans votre version, mais les messages d'erreur sont ( si vous faisiez cela, vous pourriez créer DebugLog (), WarningLog (), et ainsi de suite).
Oh, et gardez à l'esprit qu'il
#define DEBUG_MODE
peut être réutilisé à différents endroits de votre application. Par exemple, dans mon application, je l'utilise pour désactiver les vérifications de clé de licence et autoriser uniquement l'application à s'exécuter si elle est antérieure à une certaine date. Cela me permet de distribuer une version bêta entièrement fonctionnelle et limitée dans le temps avec un minimum d'effort de ma part.la source
Mettez ces 3 lignes à la fin du fichier -prefix.pch:
Vous n'avez pas besoin de définir quoi que ce soit dans votre projet, car il
DEBUG
est défini par défaut dans votre paramètre de construction lorsque vous créez votre projet.la source
Les appels NSLog peuvent être laissés dans le code de production, mais ne devraient être là que pour des cas vraiment exceptionnels ou des informations souhaitées qui seront consignées dans le journal système.
Les applications qui jonchent le journal système sont ennuyeuses et semblent non professionnelles.
la source
Je ne peux pas commenter la réponse de Marc Charbonneau , je vais donc l'afficher comme réponse.
En plus de l'ajout de la macro à votre en-tête pré-compilé, vous pouvez utiliser les configurations de construction Target pour contrôler la définition (ou l'absence de définition) du
DEBUG_MODE
.Si vous sélectionnez " Déboguer " la configuration active,
DEBUG_MODE
sera définie, et la macro se développe à laNSLog
définition complète .La sélection de la configuration active " Release " ne définira pas
DEBUG_MODE
et votreNSLog
ging est omis de la version de version.Pas:
GCC_PREPROCESSOR_DEFINITIONS
)DEBUG_MODE=1
DEBUG_MODE
n'est pas défini dansGCC_PREPROCESSOR_DEFINITIONS
si vous omettez le caractère '=' dans la définition, vous obtiendrez une erreur du préprocesseur
Collez également ce commentaire (illustré ci-dessous) au-dessus de la définition de la macro pour vous rappeler d'où
DEBUG_MACRO
vient la définition;)la source
DEBUG_MODE
et neDEBUG_MACRO
sont pas conventionnels. Je n'ai trouvé qu'une seule référenceDEBUG_MACRO
sur le site d'Apple ( opensource.apple.com/source/gm4/gm4-15/src/m4.h?txt ). Peut-être le plus standardDEBUG
etNDEBUG
serait-il de meilleurs choix?NDEBUG
est spécifié par Posix; whileDEBUG
est utilisé par convention.EDIT: La méthode publiée par Marc Charbonneau , et portée à mon attention par sho , est bien meilleure que celle-ci.
J'ai supprimé la partie de ma réponse qui suggérait d'utiliser une fonction vide pour désactiver la journalisation lorsque le mode débogage est désactivé. La partie qui traite de la définition d'une macro de préprocesseur automatique est toujours pertinente, elle le reste donc. J'ai également édité le nom de la macro du préprocesseur pour qu'elle corresponde mieux à la réponse de Marc Charbonneau.
Pour obtenir le comportement automatique (et attendu) dans Xcode:
Dans les paramètres du projet, allez dans l'onglet "Construire", et sélectionnez la configuration "Déboguer". Recherchez la section «Macros de préprocesseur» et ajoutez une macro nommée
DEBUG_MODE
....
EDIT: Voir la réponse de Marc Charbonneau pour la bonne façon d'activer et de désactiver la journalisation avec la
DEBUG_MODE
macro.la source
Je suis d'accord avec Matthew. Il n'y a rien de mal avec NSLog dans le code de production. En fait, cela peut être utile à l'utilisateur. Cela dit, si la seule raison pour laquelle vous utilisez NSLog est d'aider au débogage, alors oui, cela devrait être supprimé avant la publication.
De plus, puisque vous avez marqué cela comme une question iPhone, NSLog utilise des ressources, ce dont l'iPhone a très peu de ressources. Si vous enregistrez quelque chose sur l'iPhone, cela enlève du temps processeur à votre application. Fais-en bon usage.
la source
La simple vérité est que NSLog est tout simplement lent.
Mais pourquoi? Pour répondre à cette question, découvrons ce que fait NSLog, puis comment il le fait.
Que fait exactement NSLog?
NSLog fait 2 choses:
Il écrit les messages de journal dans la fonction Apple System Logging (asl). Cela permet aux messages du journal de s'afficher dans Console.app. Il vérifie également si le flux stderr de l'application va à un terminal (par exemple, lorsque l'application est exécutée via Xcode). Si tel est le cas, il écrit le message de journal dans stderr (pour qu'il apparaisse dans la console Xcode).
Ecrire sur STDERR ne semble pas difficile. Cela peut être accompli avec fprintf et la référence de descripteur de fichier stderr. Mais qu'en est-il de l'asl?
La meilleure documentation que j'ai trouvée sur ASL est un article de blog en 10 parties de Peter Hosey: lien
Sans entrer dans les détails, le point fort (en ce qui concerne les performances) est le suivant:
Pour envoyer un message de journal au service ASL, vous ouvrez essentiellement une connexion client au démon ASL et envoyez le message. MAIS - chaque thread doit utiliser une connexion client distincte. Par conséquent, pour être thread-safe, chaque fois que NSLog est appelé, il ouvre une nouvelle connexion client asl, envoie le message, puis ferme la connexion.
Les ressources peuvent être trouvées ici et ici .
la source
Comme indiqué dans d'autres réponses, vous pouvez utiliser un #define pour modifier si NSLog est utilisé ou non au moment de la compilation.
Cependant, un moyen plus flexible consiste à utiliser une bibliothèque de journalisation comme Cocoa Lumberjack qui vous permet de modifier si quelque chose est également journalisé lors de l'exécution.
Dans votre code, remplacez NSLog par DDLogVerbose ou DDLogError etc., ajoutez un #import pour les définitions de macro, etc. et configurez les enregistreurs, souvent dans la méthode applicationDidFinishLaunching.
Pour avoir le même effet que NSLog, le code de configuration est
la source
Du point de vue de la sécurité, cela dépend de ce qui est enregistré. Si
NSLog
(ou d'autres enregistreurs) écrit des informations sensibles, vous devez supprimer l'enregistreur dans le code de production.Du point de vue de l'audit, l'auditeur ne souhaite pas examiner chaque utilisation
NSLog
pour s'assurer de ne pas enregistrer les informations sensibles. Il / elle vous dira simplement de retirer l'enregistreur.Je travaille avec les deux groupes. Nous vérifions le code, écrivons les guides de codage, etc. Notre guide exige que la journalisation soit désactivée dans le code de production. Les équipes internes savent donc ne pas l'essayer;)
Nous rejetterons également une application externe qui se connecte en production, car nous ne voulons pas accepter le risque associé à une fuite accidentelle d'informations sensibles. Nous ne nous soucions pas de ce que le développeur nous dit. Il ne vaut tout simplement pas le temps d'enquêter.
Et rappelez-vous, nous définissons `` sensible '', et non le développeur;)
Je perçois également une application qui effectue beaucoup de journalisation comme une application prête à imploser. Il y a une raison pour laquelle tant de journalisation est effectuée / nécessaire, et ce n'est généralement pas la stabilité. C'est juste là-haut avec les threads de surveillance qui redémarrent les services bloqués.
Si vous n'avez jamais passé par un examen de l'architecture de sécurité (SecArch), voici le genre de choses que nous examinons.
la source
Vous ne devriez pas être inutilement verbeux avec printf ou NSLog dans le code de version. Essayez de ne faire un printf ou NSLog que si quelque chose de mauvais lui est arrivé, c'est-à-dire une erreur irrécupérable.
la source
Gardez à l'esprit que les NSLogs peuvent ralentir l'interface utilisateur / le thread principal. Il est préférable de les supprimer des versions de version à moins que cela ne soit absolument nécessaire.
la source
Je recommande fortement d'utiliser TestFlight pour la journalisation (gratuit). Leur méthode remplacera NSLog (à l'aide d'une macro) et vous permettra d'activer / désactiver la journalisation sur leur serveur, le journal système Apple et le journal STDERR, pour tous vos appels existants à NSLog. La bonne chose à ce sujet est que vous pouvez toujours consulter vos messages de journal pour les applications déployées sur les testeurs et les applications déployées dans l'App Store, sans que les journaux n'apparaissent dans le journal système de l'utilisateur. Le meilleur des deux mondes.
la source