121 votes

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

Lors de la sortie d'une application pour iPhone, si je désactive la fonction NSLog(); sera-t-il plus performant ?

1 votes

Dans mon projet actuel, j'utilise UALogger . Il s'agit de ne se connecte pas à la production si vous ne le demandez pas explicitement. Et a d'autres avantages par rapport à NSLog ordinaire, comme les niveaux de gravité (avec DEBUG , INFO etc) hors de la boîte. Bon travail !

1 votes

Pour répondre à votre question sur "le rendement sera-t-il meilleur ?" Oui, c'est le cas, mais le rendement que vous obtenez dépend du nombre d'heures de travail. NSLog() que vous avez à travers votre application. NSLog() prend du temps à s'exécuter et ajoute des frais supplémentaires au temps d'exécution de votre application. Quoi qu'il en soit, si une simple macro de préprocesseur DEBUG permet d'améliorer les performances, nous devrions la désactiver.

0 votes

Je dirais également que si vous avez beaucoup d'instructions NSLog/print dans votre code, cela pourrait suggérer que vous devriez passer un peu de 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 continuent automatiquement. Oui, cela peut ralentir un peu l'exécution, mais dans la plupart des cas, ce n'est pas accablant. De même, les pauses conditionnelles vous permettent d'enquêter lorsque quelque chose d'inattendu se produit.

128voto

Ramin Points 10412

Une façon de le faire est d'aller dans vos paramètres de construction et sous la configuration de débogage ajouter une valeur à la valeur "Macros du préprocesseur" comme :

DEBUG_MODE=1

Assurez-vous que vous ne faites cela que pour la configuration Debug et non pour les versions Beta 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 utiliser DLog partout. Lors des tests et du débogage, vous obtiendrez des messages de débogage. Lorsque vous serez prêt à publier une version bêta ou finale, tous ces messages de débogage seront affichés. DLog deviennent automatiquement vides et rien n'est émis. De cette manière, il n'y a pas de paramétrage manuel des variables ou de commentaire de NSLogs nécessaire. Le choix de votre cible de construction s'en charge.

0 votes

Dans Xcode 4.5 il y a un avertissement qui dit : "Implicit declaration of function 'DLog' is invalid in C99" donc cette chose ne fonctionne pas.

2 votes

@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ù elle est déclarée.

1 votes

Ne supprimez pas la journalisation car elle vous prive de la possibilité de recevoir de meilleurs rapports d'erreur de la part des utilisateurs. Utilisez la journalisation asynchrone et les niveaux de journalisation pour limiter l'impact sur les performances à presque zéro ! (voir cocoa lumberjack ou java's log4j

119voto

Whasssaaahhh Points 736

Mise à jour pour Xcode 5 et iOS 7

note : pour un Xcode 7 / Swift 2.1 solution pour éliminer print() dans un build de version, trouver ma réponse aquí .

Oui, vous devez supprimer toute déclaration NSLog dans votre code de version, car elle ne fait que ralentir votre code, et n'est d'aucune utilité dans une version de version. Heureusement, dans Xcode 5 (iOS 7), il est étonnamment simple de supprimer toutes les déclarations NSLog "automatiquement" dans les versions release. 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 'supporting files', où se trouve votre fichier main.m).

2) ajouter 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 passer par 'edit scheme' -> 'run app name' -> sous l'onglet 'info' sélectionnez en utilisant la boîte déroulante entre debug et release. Dans la version release, vous ne verrez pas de 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 "bête", et agit simplement comme un "substitut de texte" avant que le compilateur ne soit appelé. Il remplace tout ce que vous "#definez" par ce qui suit la balise #define déclaration.

#define NSLog(...);

El (...) signifie "tout" entre les crochets (). Pensez aussi au ; à la fin. Ce n'est pas strictement nécessaire car le compilateur l'optimisera, mais j'aime bien 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 jettera la ligne complète, en commençant par NSLog... jusqu'à et y compris le ; .

Les déclarations de définition peuvent être rendues conditionnelles en utilisant #ifdef (si elle est définie) ou #ifndef (si non défini)

ici nous écrivons #ifndef DEBUG ce qui signifie "si le symbole DEBUG n'est pas défini". Le site #ifdef o #ifndef doivent être "fermés" avec #endif

Xcode 5 définit par défaut le symbole 'DEBUG' pour nous lorsque le mode de construction est 'DEBUG'. En 'release', il n'est pas défini. Vous pouvez le vérifier dans les paramètres de votre projet, onglet 'Build settings' -> descendez jusqu'à la section 'Apple LLVM 5.0 - Preprocessing' -> macros du préprocesseur. Vous verrez que le symbole 'DEBUG' n'est pas défini pour les builds release !

enfin, le fichier .pch est créé automatiquement par Xcode, et automatiquement inclus dans chaque fichier source lors de la compilation. Ainsi, c'est comme si vous aviez mis tout le fichier .pch dans le fichier source. #define dans chacun de vos fichiers sources.

1 votes

Merci @Whasssaaahhh, ça marche très bien. Attention à ne pas mettre de code dans les déclarations de journal ! Le préprocesseur va supprimer l'ensemble NSLog des déclarations qui ne tiennent pas compte de ce qui se trouve à l'intérieur.

1 votes

S'il s'agit d'un ancien projet qui n'a pas le drapeau de débogage dans les macros du préprocesseur, il est important d'ajouter "debug=1" pour le projet et non pour la cible.

1 votes

De même, n'utilisez pas NSLog comme une instruction de ne rien faire, par exemple if(AllCool) NSLog(@"Cool!Do Nothing!"); else... au lieu de pop le NSLog entre des crochets if(AllCool) {NSLog(@"Cool!Do Nothing!");} else...

34voto

Andrew Points 405

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 j'ai 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 va faire deux choses : 1) écrire les messages de log dans Apple System Logging (ASL), 2) si l'application s'exécute en xcode, elle écrit aussi sur stderr.

Le principal problème réside dans le premier. Afin d'obtenir une sécurité thread, à chaque fois que NSLog est appelé, il ouvre une connexion à l'installation ASL envoie le message, et ferme la connexion. L'opération de connexion est très coûteuse. Une autre raison est que NSLog prend un certain temps pour obtenir l'horodatage à enregistrer.

Référence de aquí .

23voto

Eytan Points 1024

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

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

1 votes

Où est-ce que tu mets ça ?

0 votes

Il doit être #ifdef DEBUG et vous obtenez un code erroné, lorsqu'il n'y a pas d'accolades autour du NSLog.

21voto

NicolasMiari Points 2687

En plus de toutes les personnes qui ont judicieusement fait remarquer que ne pas appeler NSLog() du tout dans la production est légèrement plus rapide, je vais ajouter ça :

Tous ceux NSLog() les chaînes de sortie sont visibles pour toute personne qui télécharge votre application depuis le magasin et l'exécute avec l'appareil branché sur un Mac exécutant Xcode. (par la fenêtre de l'Organisateur).

En fonction des informations que vous enregistrez (et surtout si votre application contacte un serveur, procède à une authentification, etc,) cela peut être un sérieux problème de sécurité .

0 votes

Merci pour l'info - est-ce que c'est dans la documentation quelque part, ou est-ce que vous venez de le découvrir vous-même ? Est-ce toujours vrai pour l'impression en Swift ?

0 votes

Je ne me souviens pas avoir lu de documentation. J'ai juste installé ma build archivée (le même binaire que j'ai soumis au magasin) sur mon appareil et l'ai branché sur Xcode. Je n'ai aucune idée si c'est la même chose pour Swift. print() mais c'est très probable.

0 votes

@NicolasMiari Que voulez-vous dire par "branché sur Xcode" ? Comment pouvons-nous brancher notre binaire dans Xcode, en fait je veux essayer la même chose. Alors, s'il vous plaît, suggérez. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X