Нужно ли отключать NSLog перед выпуском приложения?

При выпуске приложения для iPhone, если я отключу NSLog();, он будет работать лучше?

Ответ 1

Один из способов сделать это - перейти к настройкам сборки и в конфигурации Debug добавить значение в значение "Макросы для препроцессора", например:

DEBUG_MODE=1

Убедитесь, что вы выполняете это только для конфигурации Debug, а не для версий Beta или Release. Затем в общем файле заголовка вы можете сделать что-то вроде:

#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

Теперь вместо NSLog используйте DLog всюду. При тестировании и отладке вы получите отладочные сообщения. Когда вы готовы выпустить бета-версию или финальную версию, все эти строки DLog автоматически становятся пустыми и ничего не испускают. Таким образом, не требуется ручная настройка переменных или комментирование NSLogs. Выбор вашей цели сборки позаботится об этом.

Ответ 2

Обновление для Xcode 5 и iOS 7

обратите внимание: для решения Xcode 7/Swift 2.1 для удаления инструкций print() в сборке релизов найдите мой ответ .

Да, вы должны удалить любой оператор NSLog в своем коде выпуска, так как он просто замедляет ваш код и не используется в выпускной версии. К счастью, в Xcode 5 (iOS 7) удивительно просто удалить все ваши инструкции NSLog "автоматически" в сборках релизов. Так почему бы не сделать это.

Сначала сделайте 3 шага, затем некоторое объяснение

1) в вашем проекте Xcode найдите файл 'yourProjectName-prefix.pch' (обычно вы найдете это под группой "поддерживающие файлы", где находится ваш файл main.m

2) добавьте эти 3 строки в конец файла .pch:

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

3) проверьте разницу между версией "debug" и "release". Один из способов сделать это - через "схему редактирования" → "запустите имя приложения" → под вкладкой "информация", выберите раскрывающийся список между отладкой и выпуском. В версии выпуска вы не увидите выход NSLog в консоли отладки!

Как все это работает?

Прежде всего, нужно знать, что препроцессор относительно "тупой" и просто выступает как "текстовый заменитель" перед вызовом компилятора. Он заменяет все, что вы '#define' тем, что следует за инструкцией #define.

#define NSLog(...);

(...) означает "что-либо" между скобками(). Обратите внимание также на ; в конце. Это не является абсолютно необходимым, так как компилятор будет оптимизировать это, но мне нравится указывать его, поскольку он более "правильный". После нашего #define есть "ничего", поэтому препроцессор заменит его "ничего", и поэтому он просто выбросит полную строку, начиная с NSLog... до и после ;.

Операторы

define могут быть сделаны условными, используя #ifdef (если определено) или #ifndef (если не определено)

здесь пишем #ifndef DEBUG, что означает "если символ DEBUG не определен". #ifdef или #ifndef должны быть "закрыты" с помощью #endif

Xcode 5 по умолчанию определяет символ "DEBUG" для нас, когда режим построения "DEBUG" . В 'release' это не определено. вы можете проверить это в соответствии с вашими настройками проекта, вкладкой "Настройки сборки" → прокрутить вниз до раздела "Apple LLVM 5.0 - Preprocessing" → макросы препроцессора. Вы увидите, что символ "DEBUG" не определен для релизов!

наконец, файл .pch автоматически создается Xcode и автоматически включается в каждый исходный файл во время компиляции. Таким образом, вы бы поместили всю вещь #define в каждый из ваших исходных файлов.

Ответ 3

Почти все ответы выше предлагают решение, но не объясняют проблему. Я сделал поиск в Google, и нашел причину. Вот мой ответ:

Да, если вы закомментируете NSLog в своей версии, производительность станет лучше. Потому что NSLog довольно медленный. Почему? NSLog сделает две вещи: 1) записывает сообщения журнала в Apple System Logging (ASL), 2) если приложение работает в xcode, оно также пишет в stderr.

Основная проблема кроется в первом. Для обеспечения безопасности потока каждый раз, когда вызывается NSLog, он открывает соединение со средством ASL, отправляет сообщение и закрывает соединение. Операция подключения очень дорогая. Другая причина в том, что NSLog тратит некоторое время, чтобы получить метку времени для входа.

Ссылка от здесь.

Ответ 4

Мой личный фаворит - использовать переменный макрос.

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

Ответ 5

В дополнение ко всем людям, которые разумно прокомментировали, что не вызывать NSLog() вообще в производстве, выполняется немного быстрее, я добавлю, что:

Все эти строки вывода NSLog() видны всем, кто загружает ваше приложение из магазина и запускает его с помощью устройства, подключенного к Mac, работающего под Xcode (через окно Organizer).

В зависимости от того, какую информацию вы регистрируете (и особенно, если ваше приложение связывается с сервером, выполняет аутентификацию и т.д.), это может быть серьезной проблемой безопасности.

Ответ 6

Project Default Setting

Внутри текущей настройки по умолчанию проекта в Xcode макрос NS_BLOCK_ASSERTIONS будет установлен в 1 в версии выпуска и DEBUG=1 в версии отладки.

Итак, я предпочитаю следующий метод.

// 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

Ответ 7

Да, вы должны отключить его. Особенно, если вы пытаетесь максимизировать скорость своего кода. NSLogging вещи влево и вправо загрязняет системный журнал, который другие разработчики могут пытаться прорыть, и это может сильно повлиять на критически важный код (внутри циклов и т.д.). Я случайно оставил некоторые сообщения журнала в рекурсивной функции один раз и получил выпуск обновления с "увеличением скорости на 30%!". несколько недель спустя...; -)

Ответ 8

Все хорошие ответы, однако вот еще один небольшой трюк, который вы можете использовать, в основном на этапах разработки/тестирования вашего приложения.

Он также может быть полезен и для кода выпуска приложений, если вы хотите только включить код отладки YOUR, а не сообщения, которые могут указывать на проблемы вне прямого управления вашим кодом.

Трюк:

Вы можете отключить NSLog за .m файл, просто включив строку в верхней части файла .m:

#define NSLog(...)

(ПРИМЕЧАНИЕ: НЕ помещайте этот файл .h, только файл .m!)

Это просто заставляет компилятор оценивать NSLog(), расшифровывая вместо этого макрос препроцессора. Макрос ничего не делает, кроме как вырезать аргументы.

если вы хотите снова включить его, вы всегда можете использовать

#undef NSLog

Вы могли бы, например, просто запретить вызовы NSLog вокруг определенной группы методов, выполнив что-то вроде

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

Ответ 9

NSLog медленный и не должен использоваться для сборки релиза. Простой макрос, подобный приведенному ниже, отключит его вместе с любыми утверждениями, которые могут возникнуть, которые также должны быть отключены. В менее распространенном случае, когда вы хотите NSLog в сборке релизов, просто вызовите его напрямую. Не забудьте добавить "-DNDEBUG" к настройкам сборки "других c-флагов".

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

Ответ 10

в файле pch запишите это перед #endif

#define NSLog() //

Ответ 11

как насчет этого?

#ifndef DEBUG_MODE
        fclose(stderr);     // the simplest way to disable output from NSLog
#endif    

Ответ 12

var showDebugLogs = false;

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

Это также примет дополнительные аргументы. Просто значение параметра showDebugLogs равно true или false, согласно вашей потребности.