Dans mon projet actuel, j'utilise UALogger . Il ne se connecte pas à la production , si vous ne le demandez pas explicitement. Et a d'autres avantages par rapport à NSLog standard tels que les niveaux de gravité (avec DEBUG , INFO , etc.) prêts à l'emploi . Bon travail!
Anton Gaenko le
1
Pour répondre à votre question sur "sera-t-il plus performant?" Oui, mais le rendement que vous obtenez dépend du nombre dont NSLog()vous disposez dans votre application. NSLog()prend du temps à s'exécuter et ajoute une surcharge supplémentaire à l'exécution de votre application. Quoi qu'il en soit, si cela améliore les performances avec une simple macro de préprocesseur DEBUG, nous devrions la désactiver.
Scott
Je suggérerais également que si vous avez beaucoup d'instructions NSLog / print dans votre code, cela pourrait suggérer que vous devriez passer du temps à en apprendre davantage sur le débogueur. Je fixe régulièrement des points d'arrêt qui impriment les informations qui m'intéressent, et je continue automatiquement. Oui, cela peut ralentir un peu la course, mais dans la plupart des cas, ce n'est pas écrasant. En outre, des pauses conditionnelles vous permettent d'enquêter sur les événements inattendus.
bshirley
Réponses:
127
Une façon de le faire est d'aller dans vos paramètres de construction et sous la configuration de débogage, ajoutez une valeur à la valeur "Macros de préprocesseur" comme:
DEBUG_MODE=1
Assurez-vous de ne faire cela que pour la configuration de débogage et non pour les versions Beta ou Release. Ensuite, dans un fichier d'en-tête commun, vous pouvez faire quelque chose comme:
Maintenant au lieu de l' NSLog utiliser DLogpartout. Lors du test et du débogage, vous recevrez des messages de débogage. Lorsque vous êtes prêt à publier une version bêta ou finale, toutes ces DLoglignes deviennent automatiquement vides et rien n'est émis. De cette façon, il n'y a pas de réglage manuel des variables ou de commentaire de NSLogsrequis. Le choix de votre cible de construction s'en occupe.
Dans Xcode 4.5, il donne un avertissement qui dit: "La déclaration implicite de la fonction 'DLog' n'est pas valide en C99" donc cette chose ne fonctionne pas.
Sergey Grischyov
2
@SergiusGee: Vous obtenez l'avertissement de déclaration implicite si la déclaration de la fonction est introuvable, auquel cas il pense que vous essayez de la déclarer. Assurez-vous que votre classe a accès au fichier d'en-tête où cela est déclaré.
sudo rm -rf
1
Je ne souhaite pas vous déconnecter car cela vous prive de la possibilité de recevoir de meilleurs rapports d'erreur des utilisateurs. utilisez la journalisation asynchrone et les logLevels pour limiter les performances à presque zéro! (voir cacao bûcheron ou java's log4j
Daij-Djan
2
J'irais avec #if plutôt que #ifdef, car DEBUG_MODE 0 suivra toujours le vrai chemin
Grady Player
1
cela ne répond pas à la question
Martin Mlostek
117
Mise à jour pour Xcode 5 et iOS 7
note: pour une solution Xcode 7 / Swift 2.1 pour supprimer les instructions print () dans une version de version, trouvez ma réponse ici .
Oui, vous devez supprimer toute instruction NSLog dans votre code de version, car elle ralentit simplement votre code et n'est d'aucune utilité dans une version de publication. Heureusement, dans Xcode 5 (iOS 7), il est incroyablement simple de supprimer toutes vos instructions NSLog `` automatiquement '' dans les versions de version. Alors pourquoi ne pas le faire.
D'abord les 3 étapes à suivre, puis quelques explications
1) dans votre projet Xcode, localisez le fichier 'yourProjectName-prefix.pch' (normalement vous le trouverez sous le groupe 'support files', où se trouve votre fichier main.m
2) ajoutez ces 3 lignes à la fin du fichier '.pch':
#ifndef DEBUG
#defineNSLog(...);#endif
3) testez la différence entre votre version «debug» et «release». Une façon de le faire consiste à utiliser 'modifier le schéma' -> 'exécuter le nom de l'application' -> sous l'onglet 'info', sélectionnez en utilisant la liste déroulante entre le débogage et la publication. Dans la version finale, vous ne verrez aucune sortie NSLog dans la console de débogage!
Comment ça marche?
tout d'abord, il faut savoir qu'un préprocesseur est relativement «stupide», et agit simplement comme un «remplaçant de texte» avant que le compilateur ne soit appelé. Il remplace tout ce que vous '#define' par ce qui suit l' #defineinstruction.
#defineNSLog(...);
Le (...)signifie «n'importe quoi» entre les crochets (). Attention aussi ;à la fin. Ce n'est pas strictement nécessaire car le compilateur optimisera cela, mais j'aime le mettre là, car il est plus «correct». Après notre #defineil n'y a «rien», donc le préprocesseur le remplacera par «rien», et ainsi il jettera simplement la ligne complète, en commençant par NSLog...jusqu'à et y compris le ;.
Les instructions define peuvent être rendues conditionnelles en utilisant #ifdef(si défini) ou #ifndef(si non défini)
ici nous écrivons #ifndef DEBUG, ce qui signifie «si le symbole DEBUG n'est pas défini». Le #ifdefou #ifndefdoit être `` fermé '' avec#endif
Xcode 5 définit par défaut le symbole 'DEBUG' pour nous lorsque le mode de construction est 'DEBUG'. Dans «release», cela n'est pas défini. vous pouvez le vérifier dans les paramètres de votre projet, onglet 'Paramètres de construction' -> faites défiler jusqu'à la section 'Apple LLVM 5.0 - Prétraitement' -> macros de préprocesseur. Vous verrez que le symbole «DEBUG» n'est pas défini pour les versions de version!
enfin, le fichier .pch est créé automatiquement par Xcode, et automatiquement inclus dans chaque fichier source pendant la compilation. C'est comme si vous aviez mis le tout #definedans chacun de vos fichiers source.
Merci @Whasssaaahhh, cela fonctionne très bien. Faites attention à ne pas mettre de code dans les instructions de journal! Le préprocesseur supprimera toutes les NSLoginstructions sans tenir compte de ce qui se trouve à l'intérieur.
Eric Platon
1
Si c'est un projet plus ancien qui n'a pas l'indicateur de débogage dans les macros de préprocesseur, il est important d'ajouter le "debug = 1" pour le projet et non la cible
Priebe
1
De plus, ne l'utilisez pas NSLogcomme une instruction ne rien faire, par exemple, if(AllCool) NSLog(@"Cool!Do Nothing!"); else...NSLogif(AllCool) {NSLog(@"Cool!Do Nothing!");} else...
placez
33
Presque toutes les réponses ci-dessus suggèrent une solution mais n'expliquent pas le problème. J'ai fait une recherche sur google et j'ai trouvé la raison. Voici ma réponse:
Oui, si vous commentez NSLog dans votre version, les performances seront meilleures. Parce que NSLog est assez lent. Pourquoi? NSLog fera deux choses 1) écrire des messages de journal dans Apple System Logging (ASL), 2) si l'application s'exécute dans xcode, elle écrit également dans stderr.
Le problème principal réside dans le premier. Afin de garantir la sécurité des threads, chaque fois que NSLog est appelé, il ouvre une connexion à la fonction ASL , envoie un message et ferme la connexion. L'opération de connexion est très coûteuse. Une autre raison est que NSLog passe un certain temps à obtenir l'horodatage à enregistrer.
En plus de toutes les personnes qui ont sagement commenté que ne pas appeler NSLog()du tout en production fonctionnait un peu plus vite, j'ajouterai que:
Toutes ces NSLog()chaînes de sortie sont visibles par toute personne qui télécharge votre application à partir du magasin et l'exécute avec l'appareil branché sur un mac exécutant Xcode (via la fenêtre de l'organiseur).
En fonction des informations que vous consignez (et surtout si votre application contacte un serveur, effectue une authentification, etc.), cela peut être un problème de sécurité sérieux .
merci pour l'info - est-ce quelque part dans le document ou vient-il de le découvrir vous-même? Est-ce toujours vrai pour l'impression dans Swift?
Ronny Webers
Je ne me souviens pas avoir lu de documentation. Je viens d'installer ma version archivée (le même binaire que j'ai soumis au magasin) sur mon appareil et je l'ai connectée à Xcode. Je ne sais pas si c'est la même chose pour Swift print(), mais c'est probablement le cas.
Nicolas Miari
@NicolasMiari Qu'entendez-vous par branché sur Xcode? Comment nous pouvons brancher notre binaire dans Xcode, en fait, je veux essayer la même chose. Alors veuillez suggérer. Merci.
iDevAmit le
@iDeveloper Je veux dire télécharger votre application depuis l'AppStore sur un appareil (par exemple, un iPhone), branchez cet appareil à Xcode via USB, lancez votre application et regardez les journaux dans la fenêtre «Appareils» de Xcode.
Nicolas Miari
3
L'impression @Whasssaaahhh ne s'affiche pas dans la console de l'appareil..Je viens de le tester
Anish Parajuli 웃
13
Dans le paramètre par défaut actuel du projet dans Xcode, la NS_BLOCK_ASSERTIONSmacro sera définie sur 1 dans la version commerciale et DEBUG=1dans la version Debug.
Donc, je préfère la méthode suivante.
// NS_BLOCK_ASSERTIONS is defined by default, as shown in the screenshot above.// Or, you can define yourself Flags in the `Other C Flags` -> `Release`.#ifndef NS_BLOCK_ASSERTIONS
#define _DEBUG
#endif#ifdef _DEBUG
// for debug mode #defineDLog(fmt,...)NSLog(@"%s " fmt, __FUNCTION,##__VA_ARGS__) .../// something extra#else// for release mode#defineDLog(fmt,...)/* throw it away */.../// something extra#endif
Oui, vous devez le désactiver. Surtout si vous essayez de maximiser la vitesse de votre code. NSLogging à gauche et à droite pollue le journal système que d'autres développeurs pourraient essayer de fouiller et cela peut avoir un impact important sur le code à vitesse critique (boucles internes, etc.) J'ai accidentellement laissé des messages de journal dans une fonction récursive une fois et obtenu de publier une mise à jour avec une "augmentation de vitesse de 30%!" quelques semaines plus tard... ;-)
Toutes les bonnes réponses, cependant, voici une autre petite astuce que vous pouvez envisager d'utiliser, principalement dans les phases de développement / test de votre application.
Cela peut également être utile pour le code de version d'application, si vous souhaitez uniquement désactiver VOTRE code de débogage, et non les messages qui pourraient indiquer des problèmes en dehors du contrôle direct de votre code.
L'astuce:
Vous pouvez désactiver NSLog par fichier .m en incluant simplement la ligne suivante en haut du fichier .m :
#defineNSLog(...)
( REMARQUE: ne placez PAS ce fichier .h, seulement le fichier .m! )
Cela permet simplement au compilateur d'évaluer NSLog()en développant votre macro de préprocesseur à la place. La macro ne fait rien d'autre que supprimer les arguments.
si vous souhaitez le réactiver, vous pouvez toujours utiliser
#undefNSLog
Vous pouvez par exemple simplement empêcher les appels à NSLog autour d'un groupe particulier de méthodes en faisant quelque chose comme
NSLog est lent et ne doit pas être utilisé pour les versions de version. Une simple macro comme celle ci-dessous la désactivera avec toutes les assertions que vous pourriez avoir et qui devraient également être désactivées. Dans le cas moins courant où vous voulez NSLog dans une version de version, appelez-le directement. N'oubliez pas d'ajouter "-DNDEBUG" à vos paramètres de construction "autres indicateurs c".
C'est bien, mais cela pose toujours le problème de toute la surcharge d'appel et de toute surcharge (et effets secondaires potentiels) du calcul des arguments passés à la Dlogfonction.
NSLog()
vous disposez dans votre application.NSLog()
prend du temps à s'exécuter et ajoute une surcharge supplémentaire à l'exécution de votre application. Quoi qu'il en soit, si cela améliore les performances avec une simple macro de préprocesseur DEBUG, nous devrions la désactiver.Réponses:
Une façon de le faire est d'aller dans vos paramètres de construction et sous la configuration de débogage, ajoutez une valeur à la valeur "Macros de préprocesseur" comme:
Assurez-vous de ne faire cela que pour la configuration de débogage et non pour les versions Beta ou Release. Ensuite, dans un fichier d'en-tête commun, vous pouvez faire quelque chose comme:
Maintenant au lieu de l'
NSLog
utiliserDLog
partout. Lors du test et du débogage, vous recevrez des messages de débogage. Lorsque vous êtes prêt à publier une version bêta ou finale, toutes cesDLog
lignes deviennent automatiquement vides et rien n'est émis. De cette façon, il n'y a pas de réglage manuel des variables ou de commentaire deNSLogs
requis. Le choix de votre cible de construction s'en occupe.la source
Mise à jour pour Xcode 5 et iOS 7
note: pour une solution Xcode 7 / Swift 2.1 pour supprimer les instructions print () dans une version de version, trouvez ma réponse ici .
Oui, vous devez supprimer toute instruction NSLog dans votre code de version, car elle ralentit simplement votre code et n'est d'aucune utilité dans une version de publication. Heureusement, dans Xcode 5 (iOS 7), il est incroyablement simple de supprimer toutes vos instructions NSLog `` automatiquement '' dans les versions de version. Alors pourquoi ne pas le faire.
D'abord les 3 étapes à suivre, puis quelques explications
1) dans votre projet Xcode, localisez le fichier 'yourProjectName-prefix.pch' (normalement vous le trouverez sous le groupe 'support files', où se trouve votre fichier main.m
2) ajoutez ces 3 lignes à la fin du fichier '.pch':
3) testez la différence entre votre version «debug» et «release». Une façon de le faire consiste à utiliser 'modifier le schéma' -> 'exécuter le nom de l'application' -> sous l'onglet 'info', sélectionnez en utilisant la liste déroulante entre le débogage et la publication. Dans la version finale, vous ne verrez aucune sortie NSLog dans la console de débogage!
Comment ça marche?
tout d'abord, il faut savoir qu'un préprocesseur est relativement «stupide», et agit simplement comme un «remplaçant de texte» avant que le compilateur ne soit appelé. Il remplace tout ce que vous '#define' par ce qui suit l'
#define
instruction.Le
(...)
signifie «n'importe quoi» entre les crochets (). Attention aussi;
à la fin. Ce n'est pas strictement nécessaire car le compilateur optimisera cela, mais j'aime le mettre là, car il est plus «correct». Après notre#define
il n'y a «rien», donc le préprocesseur le remplacera par «rien», et ainsi il jettera simplement la ligne complète, en commençant parNSLog...
jusqu'à et y compris le;
.Les instructions define peuvent être rendues conditionnelles en utilisant
#ifdef
(si défini) ou#ifndef
(si non défini)ici nous écrivons
#ifndef DEBUG
, ce qui signifie «si le symbole DEBUG n'est pas défini». Le#ifdef
ou#ifndef
doit être `` fermé '' avec#endif
Xcode 5 définit par défaut le symbole 'DEBUG' pour nous lorsque le mode de construction est 'DEBUG'. Dans «release», cela n'est pas défini. vous pouvez le vérifier dans les paramètres de votre projet, onglet 'Paramètres de construction' -> faites défiler jusqu'à la section 'Apple LLVM 5.0 - Prétraitement' -> macros de préprocesseur. Vous verrez que le symbole «DEBUG» n'est pas défini pour les versions de version!
enfin, le fichier .pch est créé automatiquement par Xcode, et automatiquement inclus dans chaque fichier source pendant la compilation. C'est comme si vous aviez mis le tout
#define
dans chacun de vos fichiers source.la source
NSLog
instructions sans tenir compte de ce qui se trouve à l'intérieur.NSLog
comme une instruction ne rien faire, par exemple,if(AllCool) NSLog(@"Cool!Do Nothing!"); else...
NSLog
if(AllCool) {NSLog(@"Cool!Do Nothing!");} else...
Presque toutes les réponses ci-dessus suggèrent une solution mais n'expliquent pas le problème. J'ai fait une recherche sur google et j'ai trouvé la raison. Voici ma réponse:
Oui, si vous commentez NSLog dans votre version, les performances seront meilleures. Parce que NSLog est assez lent. Pourquoi? NSLog fera deux choses 1) écrire des messages de journal dans Apple System Logging (ASL), 2) si l'application s'exécute dans xcode, elle écrit également dans stderr.
Le problème principal réside dans le premier. Afin de garantir la sécurité des threads, chaque fois que NSLog est appelé, il ouvre une connexion à la fonction ASL , envoie un message et ferme la connexion. L'opération de connexion est très coûteuse. Une autre raison est que NSLog passe un certain temps à obtenir l'horodatage à enregistrer.
Référence d' ici .
la source
Mon préféré est d'utiliser une macro variadique.
la source
En plus de toutes les personnes qui ont sagement commenté que ne pas appeler
NSLog()
du tout en production fonctionnait un peu plus vite, j'ajouterai que:Toutes ces
NSLog()
chaînes de sortie sont visibles par toute personne qui télécharge votre application à partir du magasin et l'exécute avec l'appareil branché sur un mac exécutant Xcode (via la fenêtre de l'organiseur).En fonction des informations que vous consignez (et surtout si votre application contacte un serveur, effectue une authentification, etc.), cela peut être un problème de sécurité sérieux .
la source
print()
, mais c'est probablement le cas.Dans le paramètre par défaut actuel du projet dans Xcode, la
NS_BLOCK_ASSERTIONS
macro sera définie sur 1 dans la version commerciale etDEBUG=1
dans la version Debug.Donc, je préfère la méthode suivante.
la source
Oui, vous devez le désactiver. Surtout si vous essayez de maximiser la vitesse de votre code. NSLogging à gauche et à droite pollue le journal système que d'autres développeurs pourraient essayer de fouiller et cela peut avoir un impact important sur le code à vitesse critique (boucles internes, etc.) J'ai accidentellement laissé des messages de journal dans une fonction récursive une fois et obtenu de publier une mise à jour avec une "augmentation de vitesse de 30%!" quelques semaines plus tard... ;-)
la source
Toutes les bonnes réponses, cependant, voici une autre petite astuce que vous pouvez envisager d'utiliser, principalement dans les phases de développement / test de votre application.
Cela peut également être utile pour le code de version d'application, si vous souhaitez uniquement désactiver VOTRE code de débogage, et non les messages qui pourraient indiquer des problèmes en dehors du contrôle direct de votre code.
L'astuce:
Vous pouvez désactiver NSLog par fichier .m en incluant simplement la ligne suivante en haut du fichier .m :
( REMARQUE: ne placez PAS ce fichier .h, seulement le fichier .m! )
Cela permet simplement au compilateur d'évaluer
NSLog()
en développant votre macro de préprocesseur à la place. La macro ne fait rien d'autre que supprimer les arguments.si vous souhaitez le réactiver, vous pouvez toujours utiliser
Vous pouvez par exemple simplement empêcher les appels à NSLog autour d'un groupe particulier de méthodes en faisant quelque chose comme
la source
NSLog est lent et ne doit pas être utilisé pour les versions de version. Une simple macro comme celle ci-dessous la désactivera avec toutes les assertions que vous pourriez avoir et qui devraient également être désactivées. Dans le cas moins courant où vous voulez NSLog dans une version de version, appelez-le directement. N'oubliez pas d'ajouter "-DNDEBUG" à vos paramètres de construction "autres indicateurs c".
la source
dans le fichier pch, écrivez ceci avant #endif
la source
Et ça?
la source
Cela acceptera également les arguments supplémentaires. Juste la valeur du paramètre showDebugLogs à true ou false, selon vos besoins
la source
Dlog
fonction.