Czy muszę wyłączyć NSLog przed wydaniem aplikacji?

Po zwolnieniu aplikacji na iPhone, jeśli wyłączę NSLog(); czy będzie ona działać lepiej?

Author: Nicolas Miari, 2010-01-08

12 answers

Jednym ze sposobów, aby to zrobić, jest przejście do ustawień kompilacji i pod konfiguracją debugowania dodać wartość "makr preprocesora", jak:

DEBUG_MODE=1

Upewnij się, że robisz to tylko dla konfiguracji debugowania, a nie dla wersji Beta lub Release. Następnie we wspólnym pliku nagłówkowym możesz zrobić coś w stylu:

#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

Teraz zamiast NSLog Użyj DLog wszędzie. Podczas testowania i debugowania otrzymasz wiadomości debugowania. Kiedy będziesz gotowy do wydania wersji beta lub finalnej, wszystkie te DLog linie automatycznie stają się puste i nic nie jest emitowane. W ten sposób nie jest wymagane ręczne ustawianie zmiennych ani komentowanie NSLogs. Wybranie celu budowy zajmie się tym.

 124
Author: Ramin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-08 05:40:40

Aktualizacja dla Xcode 5 i iOS 7

uwaga: dla Xcode 7 / Swift 2.1 rozwiązanie do usuwania Print () instrukcji w kompilacji release, Znajdź moją odpowiedź tutaj .

Tak, powinieneś usunąć dowolną instrukcję NSLog w kodzie wydania, ponieważ po prostu spowalnia twój kod i nie jest użyteczny w wersji wydania. Na szczęście w Xcode 5 (iOS 7) niezwykle proste jest usuwanie wszystkich instrukcji NSLog "automatycznie" w release builds. Więc dlaczego nie rób tego.

Najpierw 3 kroki do wykonania, potem jakieś wyjaśnienie

1) w projekcie Xcode znajdź prefiks ' yourProjectName -.PCH 'file (normalnie znajdziesz go w grupie 'supporting files' , gdzie jest twój główny.plik m znajduje się

2) dodaj te 3 linie na końcu '.plik pch:

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

3) przetestuj różnicę między wersją' debug 'i' release'. Jednym ze sposobów jest "edytuj schemat" - > "Uruchom nazwę aplikacji" - > w zakładce "Informacje" wybierz z listy rozwijanej pomiędzy debugowaniem i wydaniem. W wersji release nie zobaczysz żadnego wyjścia NSLog w konsoli debugowania !

Jak to wszystko działa?

Po pierwsze, trzeba wiedzieć, że preprocesor jest stosunkowo 'głupi' i działa jako 'zamiennik tekstu', zanim kompilator zostanie wywołany. Zastępuje wszystko, co '# definiujesz' przez to, co następuje po instrukcji #define.

#define NSLog(...);

(...) oznacza "cokolwiek" pomiędzy nawiasami (). Umysł także ; w koniec. Nie jest to absolutnie konieczne, ponieważ kompilator to zoptymalizuje, ale lubię to tam umieścić, ponieważ jest bardziej 'poprawne'. Po #define nie ma 'nic', więc preprocesor zastąpi go 'nic', a więc po prostu wyrzuci całą linię, zaczynając od NSLog... aż do ;.

Wyrażenia definiujące mogą być warunkowe za pomocą #ifdef (jeśli zdefiniowano) lub #ifndef (Jeśli nie zdefiniowano)

Tutaj piszemy #ifndef DEBUG, co oznacza "jeśli symbol DEBUG nie jest zdefiniowane". #ifdef lub #ifndef muszą być "zamknięte" przez #endif

Xcode 5 domyślnie definiuje dla nas symbol 'DEBUG', gdy tryb DE build to 'DEBUG'. W 'release' nie jest to zdefiniowane. możesz to sprawdzić w ustawieniach projektu, zakładka "Ustawienia kompilacji" - > przewiń w dół do sekcji "Apple LLVM 5.0-przetwarzanie wstępne" - > makra preprocesora. Zobaczysz, że symbol 'DEBUG' nie jest zdefiniowany dla wersji kompilacji!

Wreszcie,plik PCH jest tworzony przez Xcode automatycznie, a automatycznie dołączany do każdego pliku źródłowego podczas kompilacji. Więc to tak, jakbyś włożył całą #define rzecz do każdego ze swoich plików źródłowych.

 113
Author: Ronny Webers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:10

Prawie wszystkie powyższe odpowiedzi sugerują rozwiązanie, ale nie wyjaśniają problemu. Szukałem w google i znalazłem powód. Oto moja odpowiedź:

Tak, jeśli skomentujesz NSLog w wersji release, wydajność stanie się lepsza. Bo NSLog jest dość powolny.Dlaczego? NSLog zrobi dwie rzeczy: 1) zapisuje komunikaty logowania do systemu Apple Logging (ASL), 2) Jeśli aplikacja działa w xcode to również zapisuje na stderr.

Główny problem leży w pierwszym. W celu osiągnięcia thread safe, za każdym razem, gdy nslog jest wywołany, otwiera połączenie do obiektu ASL , wysyła wiadomość i zamyka połączenie. Operacja połączenia jest bardzo kosztowna. Innym powodem jest to, że NSLog poświęca trochę czasu na uzyskanie znacznika czasu do logowania.

Odniesienie z tutaj .

 30
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-19 05:27:15

Moim ulubionym jest używanie różnych makr.

#ifdef NDEBUG
    #define NSLog(...) /* suppress NSLog when in release mode */
#endif
 23
Author: Eytan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-11 00:17:28

Oprócz wszystkich osób, które mądrze skomentowały, że nie wywołanie NSLog() w ogóle w produkcji działa nieco szybciej, dodam, że:

Wszystkie te NSLog() ciągi wyjściowe są widoczne dla każdego, kto pobiera aplikację ze sklepu i uruchamia ją z urządzeniem podłączonym do komputera mac z Xcode (przez okno organizera).

W zależności od tego, jakie informacje rejestrujesz (a zwłaszcza jeśli Twoja aplikacja kontaktuje się z serwerem, wykonuje uwierzytelnianie itp.), to może być poważne problem bezpieczeństwa .

 17
Author: Nicolas Miari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 10:05:40

Domyślne Ustawienie Projektu

Wewnątrz domyślnego ustawienia projektu w Xcode, Makro NS_BLOCK_ASSERTIONS zostanie ustawione na 1 w wersji release, a DEBUG=1 w wersji Debug.

Więc wolę następującą metodę.

// 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
Author: AechoLiu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-24 05:34:30

Tak, powinieneś go wyłączyć. Zwłaszcza jeśli próbujesz zmaksymalizować szybkość kodu. NSLogging rzeczy w lewo i w prawo zanieczyszcza dziennik systemowy, który inni programiści mogą próbować przekopać i może mieć duży wpływ na kod krytyczny dla prędkości (wewnątrz pętli, itp..) Przypadkowo zostawiłem kilka wiadomości dziennika w funkcji rekurencyjnej raz i dostałem do wydania aktualizacji z " 30% wzrost prędkości!"kilka tygodni później... ;-)

 5
Author: Ben Gotow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-08 04:36:25

Wszystkie dobre odpowiedzi, jednak oto kolejna mała sztuczka, którą możesz rozważyć, głównie w fazie rozwoju/testowania aplikacji.

Może być również przydatny dla kodu wydania aplikacji, Jeśli chcesz tylko włączyć kod debugowania, a nie wiadomości, które mogą wskazywać problemy poza bezpośrednią kontrolą kodu.

Sztuczka:

możesz wyłączyć NSLog per .m plik po prostu w tym follow line na górze .plik m :

#define NSLog(...)

(uwaga: do NOT put this the .plik h, tylko .plik m!)

To sprawia, że kompilator ocenia {[3] } rozszerzając makro preprocesora. Makro nie robi nic poza usunięciem argumentów.

Jeśli chcesz go ponownie włączyć, zawsze możesz użyć

#undef NSLog

Możesz na przykład zapobiec wywołaniom NSLog wokół określonej grupy metod, wykonując coś takiego jak

#define NSLog(...)
-(void) myProblematicMethodThatSometimesNeedsDebugging {
    ...
}
#undef NSLog
 5
Author: unsynchronized,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 00:35:27

NSLog jest powolny i nie powinien być używany do kompilacji release. Proste makro, takie jak poniżej, wyłączy je wraz z wszelkimi twierdzeniami, które możesz mieć, które również powinny być wyłączone. W mniej powszechnym przypadku, gdy chcesz nslog w kompilacji release, po prostu zadzwoń do niego bezpośrednio. Nie zapomnij dodać "- DNDEBUG "do ustawień budowania " inne flagi c".

#ifdef NDEBUG
#define MYLog(f, ...) 
#else
#define MYLog(f, ...) NSLog(f, ## __VA_ARGS__)
#endif
 3
Author: papahabla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-17 05:53:55

W pliku pch zapisz to przed #endif

#define NSLog() //
 2
Author: Sandeep Saurabh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-26 17:00:40

A co z tym?

#ifndef DEBUG_MODE
        fclose(stderr);     // the simplest way to disable output from NSLog
#endif    
 0
Author: roberto.buratti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-15 19:48:00
var showDebugLogs = false;

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

To również zaakceptuje dodatkowe argumenty.. Po prostu wartość parametru showDebugLogs na true lub false, zgodnie z potrzebą

 0
Author: Zahur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-02 09:42:40