При выпуске приложения для iPhone, если я отключу NSLog();
, он будет работать лучше?
Нужно ли отключать 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
Внутри текущей настройки по умолчанию проекта в 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, согласно вашей потребности.