web-dev-qa-db-fra.com

Dois-je désactiver NSLog avant de publier l'application?

Lors de la publication d'une application pour iPhone, si je désactive NSLog(); est-ce que cela fonctionnera mieux?

115
RAGOpoR

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 le faire que pour la configuration de débogage et non pour les versions Bêta ou Release. Ensuite, dans un fichier d'en-tête commun, vous pouvez faire quelque chose comme:

#ifdef DEBUG_MODE
#define DLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog( s, ... ) 
#endif

Maintenant, au lieu de NSLog, utilisez DLog partout. Lors des tests et du débogage, vous obtiendrez des messages de débogage. Lorsque vous êtes prêt à publier une version bêta ou finale, toutes ces lignes DLog deviennent automatiquement vides et rien n'est émis. De cette façon, aucun réglage manuel des variables ou commentaire de NSLogs n'est requis. Choisir votre cible de construction s'en occupe.

125
Ramin

Mise à jour pour Xcode 5 et iOS 7

note: pour une Xcode 7/Swift 2.1 solution à supprimer instructions print () dans une 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 version. Heureusement, dans Xcode 5 (iOS 7), il est incroyablement simple de supprimer toutes vos instructions NSLog "automatiquement" dans les versions. 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 dans le groupe 'fichiers de support', où se trouve votre fichier main.m

2) ajoutez ces 3 lignes à la fin du fichier '.pch':

#ifndef DEBUG
   #define NSLog(...);
#endif

3) testez la différence entre votre version 'debug' et 'release'. Une façon de le faire est de "modifier le schéma" -> "exécuter le nom de l'application" -> sous l'onglet "info", sélectionnez en utilisant la liste déroulante entre débogage et libération. Dans la version finale, vous ne verrez aucune sortie NSLog dans la console de débogage!

Comment tout cela fonctionne-t-il?

tout d'abord, il faut savoir qu'un préprocesseur est relativement "stupide", et agit simplement comme un "remplaçant de texte" avant d'appeler le compilateur. Il remplace tout ce que vous '#define' par ce qui suit le #define déclaration.

#define NSLog(...);

Le (...) représente "n'importe quoi" entre les crochets (). Attention aussi au ; à la fin. Ce n'est pas strictement nécessaire car le compilateur optimisera cela, mais j'aime le mettre là, car c'est plus "correct". Après notre #define il n'y a 'rien', donc le préprocesseur le remplacera par 'rien', et donc il ne fera que jeter la ligne complète, en commençant à NSLog... jusqu'à et y compris le ;.

les instructions define peuvent être conditionnées en utilisant #ifdef (si défini) ou #ifndef (si non défini)

ici on écrit #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 "version", cela n'est pas défini. vous pouvez le vérifier sous 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 auriez mis l'ensemble #define chose dans chacun de vos fichiers source.

116
Ronny Webers

Presque toutes les réponses ci-dessus suggèrent une solution mais n'expliquent pas le problème. J'ai fait une recherche dans google et trouvé la raison. Voici ma réponse:

Oui, si vous commentez NSLog dans votre version, les performances s'amélioreront. 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 aussi dans stderr.

Le principal problème 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 de ici .

31
Andrew

Mon préféré est d'utiliser une macro variadique.

#ifdef NDEBUG
    #define NSLog(...) /* suppress NSLog when in release mode */
#endif
23
Eytan

En plus de toutes les personnes qui ont sagement commenté que le fait de ne pas appeler NSLog() du tout en production fonctionne un peu plus vite, j'ajouterai que:

Toutes ces chaînes de sortie NSLog() sont visibles par toute personne qui télécharge votre application depuis la boutique et l'exécute avec l'appareil branché sur un mac exécutant Xcode (via la fenêtre Organiseur).

Selon les informations que vous enregistrez (et surtout si votre application contacte un serveur, fait l'authentification, etc.), cela peut être un grave problème de sécurité.

19
Nicolas Miari

Project Default Setting

Dans le paramètre par défaut actuel du projet dans Xcode, le NS_BLOCK_ASSERTIONS la macro sera définie sur 1 dans la version finale et DEBUG=1 dans 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 
#define DLog(fmt,...) NSLog(@"%s " fmt, __FUNCTION, ##__VA_ARGS__) 
... /// something extra
#else
// for release mode
#define DLog(fmt,...) /* throw it away */
... /// something extra
#endif
13
AechoLiu

Oui, vous devez le désactiver. Surtout si vous essayez de maximiser la vitesse de votre code. NSLogging choses à gauche et à droite pollue le journal système que d'autres développeurs pourraient essayer de creuser et cela peut avoir un grand impact sur le code critique de vitesse (à l'intérieur des boucles, etc.) J'ai accidentellement laissé quelques messages de journal dans une fonction récursive une fois et obtenu de publier une mise à jour avec une "augmentation de 30% de la vitesse!" quelques semaines plus tard... ;-)

5
Ben Gotow

Toutes les bonnes réponses, mais voici une autre petite astuce que vous pouvez envisager d'utiliser, principalement dans les phases de développement/test de votre application.

Il peut également être utile pour le code de version de l'application, si vous souhaitez uniquement désactiver VOTRE code de débogage, et non les messages qui pourraient indiquer des problèmes hors du contrôle direct de votre code.

L'astuce:

Vous pouvez désactiver NSLog par fichier .m en incluant simplement la ligne de suivi en haut du fichier .m :

#define NSLog(...)

(NOTE: faites [~ # ~] pas [~ # ~] mettez ceci le fichier .h, seulement le fichier .m!)

Cela fait simplement que le compilateur évalue NSLog() en développant votre macro de préprocesseur à la place. La macro ne fait que supprimer les arguments.

si vous souhaitez le réactiver, vous pouvez toujours utiliser

#undef NSLog

Vous pouvez par exemple simplement empêcher les appels à NSLog autour d'un groupe particulier de méthodes en faisant quelque chose comme

#define NSLog(...)
-(void) myProblematicMethodThatSometimesNeedsDebugging {
    ...
}
#undef NSLog
5
unsynchronized

NSLog est lent et ne doit pas être utilisé pour les versions de version. Une simple macro comme celle ci-dessous le 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, appelez-le directement. N'oubliez pas d'ajouter "-DNDEBUG" à vos paramètres de construction "autres drapeaux c".

#ifdef NDEBUG
#define MYLog(f, ...) 
#else
#define MYLog(f, ...) NSLog(f, ## __VA_ARGS__)
#endif
3
papahabla

dans le fichier pch, écrivez ceci avant #endif

#define NSLog() //
2
Sandeep Saurabh

et ça?

#ifndef DEBUG_MODE
        fclose(stderr);     // the simplest way to disable output from NSLog
#endif    
0
roberto.buratti
var showDebugLogs = false;

    func DLog(format: String, args: CVarArgType...) {
        if showDebugLogs{
        println(String(format: format, arguments: args))
        }
    }

Cela acceptera également les arguments supplémentaires. Juste la valeur du paramètre showDebugLogs sur true ou false, selon vos besoins

0
Zahur