В моем текущем проекте я использую UALogger . Он не входит в производство , если вы не спрашиваете об этом явно. И имеет другие преимущества по сравнению с обычным NSLog, такие как уровни серьезности (с DEBUG , INFO и т. Д.) Из коробки. Хорошая работа!
Антон Гаенко
1
Чтобы ответить на ваш вопрос "будет ли он работать лучше?" Да, это так, но получаемая вами доходность зависит от того, сколько у NSLog()вас их в приложении. NSLog()требует времени для выполнения и добавляет дополнительные накладные расходы во время выполнения вашего приложения. В любом случае, если это помогает в производительности с помощью простого макроса препроцессора DEBUG, мы должны отключить его.
Скотт
Я также предлагаю, если в вашем коде много операторов NSLog / print, это может предложить вам потратить некоторое время на изучение отладчика. Я регулярно устанавливаю точки останова, которые выводят на печать интересующую меня информацию и автоматически продолжаю. Да, это может немного замедлить работу, но в большинстве случаев это не слишком сильно. Кроме того, условные перерывы, чтобы вы могли расследовать, когда произошло что-то неожиданное.
bshirley
Ответы:
127
Один из способов сделать это - зайти в настройки сборки и в разделе «Отладка» добавить значение «Макросы препроцессора», например:
DEBUG_MODE=1
Убедитесь, что вы делаете это только для конфигурации отладки, а не для версий Beta или Release. Затем в общем файле заголовка вы можете сделать что-то вроде:
Теперь вместо NSLog использования DLogвезде. При тестировании и отладке вы получите отладочные сообщения. Когда вы готовы выпустить бета-версию или финальную версию, все эти DLogстроки автоматически становятся пустыми и ничего не выводится. Таким образом, не NSLogsтребуется ручная установка переменных или их комментирование . Выбор цели сборки позаботится об этом.
В Xcode 4.5 он выдает предупреждение, в котором говорится: «Неявное объявление функции DLog недопустимо в C99», поэтому эта вещь не работает.
Сергей Грищев
2
@SergiusGee: вы получаете предупреждение о неявном объявлении, если объявление для функции не может быть найдено, и в этом случае он думает, что вы пытаетесь его объявить. Убедитесь, что ваш класс имеет доступ к файлу заголовка, в котором он объявлен.
sudo rm -rf
1
Id не запрещает выход из системы, поскольку это лишает вас возможности получать более качественные отчеты об ошибках от пользователей. используйте асинхронное ведение журнала и logLevels, чтобы ограничить снижение производительности почти до нуля! (см. cocoa
lumberjack
2
Я бы выбрал #if, а не #ifdef, так как DEBUG_MODE 0 по-прежнему будет проходить истинный путь
Grady Player
1
это не отвечает на вопрос
Мартин Млостек
117
Обновление для Xcode 5 и iOS 7
примечание: для решения Xcode 7 / Swift 2.1 для удаления операторов print () в сборке выпуска найдите мой ответ здесь .
Да, вам следует удалить любой оператор NSLog в коде выпуска, так как он просто замедляет ваш код и не используется в выпускной версии. К счастью, в Xcode 5 (iOS 7) удивительно просто удалить все ваши операторы NSLog «автоматически» в сборках выпуска. Так почему бы не сделать это.
Сначала три шага, которые нужно предпринять, затем объяснение
1) в вашем проекте Xcode найдите файл yourProjectName-prefix.pch (обычно вы найдете его в группе «вспомогательные файлы», где находится ваш файл main.m
2) добавьте эти 3 строки в конец файла .pch:
#ifndef DEBUG
#defineNSLog(...);#endif
3) проверьте разницу между вашей «отладочной» и «выпускной» версией. Один из способов сделать это - «изменить схему» -> «запустить имя приложения» -> на вкладке «информация» выбрать в раскрывающемся списке между отладкой и выпуском. В выпускной версии вы не увидите вывода NSLog в консоли отладки!
Как это все работает?
Прежде всего, нужно знать, что препроцессор относительно «тупой» и просто действует как «заменитель текста» перед вызовом компилятора. Он заменяет все, что вы '#define', тем, что следует за #defineоператором.
#defineNSLog(...);
(...)Означает «ничего» между скобками (). Помните также ;о конце. Это не является строго необходимым, поскольку компилятор оптимизирует это, но мне нравится помещать это там, поскольку это более «правильно». После нашего #defineидет «ничего», поэтому препроцессор заменит его на «ничего», и поэтому он просто выбросит всю строку, начиная с NSLog...до и включая; .
Операторы define могут быть условными с помощью #ifdef(если определено) или#ifndef (если не определено)
здесь мы пишем #ifndef DEBUG, что означает «если символ DEBUG не определен». #ifdefили#ifndef потребность быть «закрытым» с#endif
Xcode 5 по умолчанию определяет для нас символ «DEBUG», когда режим сборки - «DEBUG». В «выпуске» это не определено. вы можете проверить это в настройках вашего проекта, на вкладке «Параметры сборки» -> прокрутите вниз до раздела «Apple LLVM 5.0 - Предварительная обработка» -> макросы препроцессора. Вы увидите, что символ «DEBUG» не определен для сборок выпуска!
наконец, файл .pch создается Xcode автоматически и автоматически включается в каждый исходный файл во время компиляции. Это как если бы вы поместили все #defineэто в каждый из ваших исходных файлов.
Спасибо @Whasssaaahhh, отлично работает. Будьте осторожны, чтобы не помещать код в операторы журнала! Препроцессор удалит все NSLogоператоры, не обращая внимания на то, что находится внутри.
Эрик Платон,
1
Если это более старый проект, у которого нет флага отладки в макросах препроцессора, важно добавить «debug = 1» для проекта, а не для цели
Прибе
1
Кроме того, не используйте NSLogвыражение «ничего не делать», например, if(AllCool) NSLog(@"Cool!Do Nothing!"); else...вместо этого NSLogif(AllCool) {NSLog(@"Cool!Do Nothing!");} else...
вставьте
33
Почти все приведенные выше ответы предлагают решение, но не объясняют проблему. Я поискал в гугле и нашел причину. Вот мой ответ:
Да, если вы закомментируете NSLog в своей релизной версии, производительность станет лучше. Потому что NSLog довольно медленный. Зачем? NSLog будет делать две вещи: 1) записывать сообщения журнала в системный журнал Apple (ASL), 2) если приложение работает в xcode, оно также записывает в stderr.
Основная проблема заключается в первом. Чтобы обеспечить потокобезопасность, каждый раз , когда вызывается NSLog, он открывает соединение с функцией ASL , отправляет сообщение и закрывает соединение. Операция подключения очень дорогая. Другая причина заключается в том, что NSLog тратит некоторое время на получение отметки времени для регистрации.
В дополнение ко всем людям, которые мудро прокомментировали, что отсутствие звонков NSLog()в продакшн работает немного быстрее, я добавлю следующее:
Все эти NSLog()выходные строки видны всем, кто загружает ваше приложение из магазина и запускает его с устройством, подключенным к Mac, на котором запущен Xcode. (через окно Организатора).
В зависимости от того, какую информацию вы регистрируете (и особенно если ваше приложение связывается с сервером, выполняет аутентификацию и т. Д.), Это может быть серьезной проблемой безопасности .
спасибо за информацию - это где-то в документации, или вы сами это обнаружили? Это все еще верно для печати в Swift?
Ронни Веберс
Я не помню, чтобы читал документацию. Я только что установил свою заархивированную сборку (тот же двоичный файл, который я отправил в магазин) на свое устройство и подключил его к Xcode. Понятия не имею, то же самое для Swift print(), но, скорее всего, это так.
Николас Миари
@NicolasMiari Что вы имеете в виду, говоря о подключении к Xcode? Как мы можем подключить наш двоичный код к Xcode, я хочу попробовать то же самое. Пожалуйста, предложите. Спасибо.
iDevAmit
@iDeveloper Я имею в виду загрузите ваше приложение из AppStore на устройство (например, iPhone), подключите это устройство к Xcode через USB, запустите приложение и посмотрите журналы в окне Xcode «Устройства».
Николас Миари
3
@Whasssaaahhh печать не выводится в консоль устройства .. Я только что проверил это
Аниш Параджули 웃
13
Внутри текущей настройки проекта по умолчанию в 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 #defineDLog(fmt,...)NSLog(@"%s " fmt, __FUNCTION,##__VA_ARGS__) .../// something extra#else// for release mode#defineDLog(fmt,...)/* throw it away */.../// something extra#endif
Да, вы должны отключить его. Особенно, если вы пытаетесь максимизировать скорость своего кода. NSLogging вещей слева и справа загрязняет системный журнал, который другие разработчики могут пытаться раскопать, и может иметь большое влияние на критичный по скорости код (внутренние циклы и т. Д.) Я случайно оставил некоторые сообщения журнала в рекурсивной функции один раз и должен выпустить обновление с «увеличением скорости на 30%!» несколько недель спустя ... ;-)
Все хорошие ответы, однако вот еще один небольшой трюк, который вы можете использовать, в основном, на этапах разработки / тестирования вашего приложения.
Это также может быть полезно для кода выпуска приложения, если вы хотите отключить только ВАШ код отладки, а не сообщения, которые могут указывать на проблемы, находящиеся вне прямого контроля вашего кода.
Хитрость:
Вы можете отключить NSLog для файла .m, просто включив следующую строку в верхней части файла .m :
#defineNSLog(...)
( ПРИМЕЧАНИЕ: НЕ помещайте это файл .h, только файл .m! )
Это просто заставляет компилятор вычислять NSLog(), вместо этого расширяя ваш макрос препроцессора. Макрос ничего не делает, только удаляет аргументы.
если вы хотите снова включить его, вы всегда можете использовать
#undefNSLog
Вы можете, например, просто предотвратить вызовы NSLog вокруг определенной группы методов, выполнив что-то вроде
NSLog работает медленно и не должен использоваться для сборок выпуска. Простой макрос, подобный приведенному ниже, отключит его вместе со всеми возможными утверждениями, которые также следует отключить. В менее распространенном случае, когда вам нужен NSLog в сборке выпуска, просто вызовите его напрямую. Не забудьте добавить «-DNDEBUG» в настройки сборки «другие флаги c».
Это хорошо, но по-прежнему имеет проблему накладных расходов на вызовы и любых накладных расходов (и потенциальных побочных эффектов) при вычислении любых аргументов, переданных Dlogфункции.
NSLog()
вас их в приложении.NSLog()
требует времени для выполнения и добавляет дополнительные накладные расходы во время выполнения вашего приложения. В любом случае, если это помогает в производительности с помощью простого макроса препроцессора DEBUG, мы должны отключить его.Ответы:
Один из способов сделать это - зайти в настройки сборки и в разделе «Отладка» добавить значение «Макросы препроцессора», например:
Убедитесь, что вы делаете это только для конфигурации отладки, а не для версий Beta или Release. Затем в общем файле заголовка вы можете сделать что-то вроде:
Теперь вместо
NSLog
использованияDLog
везде. При тестировании и отладке вы получите отладочные сообщения. Когда вы готовы выпустить бета-версию или финальную версию, все этиDLog
строки автоматически становятся пустыми и ничего не выводится. Таким образом, неNSLogs
требуется ручная установка переменных или их комментирование . Выбор цели сборки позаботится об этом.источник
Обновление для Xcode 5 и iOS 7
примечание: для решения Xcode 7 / Swift 2.1 для удаления операторов print () в сборке выпуска найдите мой ответ здесь .
Да, вам следует удалить любой оператор NSLog в коде выпуска, так как он просто замедляет ваш код и не используется в выпускной версии. К счастью, в Xcode 5 (iOS 7) удивительно просто удалить все ваши операторы NSLog «автоматически» в сборках выпуска. Так почему бы не сделать это.
Сначала три шага, которые нужно предпринять, затем объяснение
1) в вашем проекте Xcode найдите файл yourProjectName-prefix.pch (обычно вы найдете его в группе «вспомогательные файлы», где находится ваш файл main.m
2) добавьте эти 3 строки в конец файла .pch:
3) проверьте разницу между вашей «отладочной» и «выпускной» версией. Один из способов сделать это - «изменить схему» -> «запустить имя приложения» -> на вкладке «информация» выбрать в раскрывающемся списке между отладкой и выпуском. В выпускной версии вы не увидите вывода NSLog в консоли отладки!
Как это все работает?
Прежде всего, нужно знать, что препроцессор относительно «тупой» и просто действует как «заменитель текста» перед вызовом компилятора. Он заменяет все, что вы '#define', тем, что следует за
#define
оператором.(...)
Означает «ничего» между скобками (). Помните также;
о конце. Это не является строго необходимым, поскольку компилятор оптимизирует это, но мне нравится помещать это там, поскольку это более «правильно». После нашего#define
идет «ничего», поэтому препроцессор заменит его на «ничего», и поэтому он просто выбросит всю строку, начиная сNSLog...
до и включая;
.Операторы define могут быть условными с помощью
#ifdef
(если определено) или#ifndef
(если не определено)здесь мы пишем
#ifndef DEBUG
, что означает «если символ DEBUG не определен».#ifdef
или#ifndef
потребность быть «закрытым» с#endif
Xcode 5 по умолчанию определяет для нас символ «DEBUG», когда режим сборки - «DEBUG». В «выпуске» это не определено. вы можете проверить это в настройках вашего проекта, на вкладке «Параметры сборки» -> прокрутите вниз до раздела «Apple LLVM 5.0 - Предварительная обработка» -> макросы препроцессора. Вы увидите, что символ «DEBUG» не определен для сборок выпуска!
наконец, файл .pch создается Xcode автоматически и автоматически включается в каждый исходный файл во время компиляции. Это как если бы вы поместили все
#define
это в каждый из ваших исходных файлов.источник
NSLog
операторы, не обращая внимания на то, что находится внутри.NSLog
выражение «ничего не делать», например,if(AllCool) NSLog(@"Cool!Do Nothing!"); else...
вместо этогоNSLog
if(AllCool) {NSLog(@"Cool!Do Nothing!");} else...
Почти все приведенные выше ответы предлагают решение, но не объясняют проблему. Я поискал в гугле и нашел причину. Вот мой ответ:
Да, если вы закомментируете NSLog в своей релизной версии, производительность станет лучше. Потому что NSLog довольно медленный. Зачем? NSLog будет делать две вещи: 1) записывать сообщения журнала в системный журнал Apple (ASL), 2) если приложение работает в xcode, оно также записывает в stderr.
Основная проблема заключается в первом. Чтобы обеспечить потокобезопасность, каждый раз , когда вызывается NSLog, он открывает соединение с функцией ASL , отправляет сообщение и закрывает соединение. Операция подключения очень дорогая. Другая причина заключается в том, что NSLog тратит некоторое время на получение отметки времени для регистрации.
Ссылка отсюда .
источник
Лично я предпочитаю использовать макрос с переменными числами.
источник
В дополнение ко всем людям, которые мудро прокомментировали, что отсутствие звонков
NSLog()
в продакшн работает немного быстрее, я добавлю следующее:Все эти
NSLog()
выходные строки видны всем, кто загружает ваше приложение из магазина и запускает его с устройством, подключенным к Mac, на котором запущен Xcode. (через окно Организатора).В зависимости от того, какую информацию вы регистрируете (и особенно если ваше приложение связывается с сервером, выполняет аутентификацию и т. Д.), Это может быть серьезной проблемой безопасности .
источник
print()
, но, скорее всего, это так.Внутри текущей настройки проекта по умолчанию в Xcode
NS_BLOCK_ASSERTIONS
макрос будет установлен в 1 в версии выпуска иDEBUG=1
в версии отладки.Итак, я предпочитаю следующий метод.
источник
Да, вы должны отключить его. Особенно, если вы пытаетесь максимизировать скорость своего кода. NSLogging вещей слева и справа загрязняет системный журнал, который другие разработчики могут пытаться раскопать, и может иметь большое влияние на критичный по скорости код (внутренние циклы и т. Д.) Я случайно оставил некоторые сообщения журнала в рекурсивной функции один раз и должен выпустить обновление с «увеличением скорости на 30%!» несколько недель спустя ... ;-)
источник
Все хорошие ответы, однако вот еще один небольшой трюк, который вы можете использовать, в основном, на этапах разработки / тестирования вашего приложения.
Это также может быть полезно для кода выпуска приложения, если вы хотите отключить только ВАШ код отладки, а не сообщения, которые могут указывать на проблемы, находящиеся вне прямого контроля вашего кода.
Хитрость:
Вы можете отключить NSLog для файла .m, просто включив следующую строку в верхней части файла .m :
( ПРИМЕЧАНИЕ: НЕ помещайте это файл .h, только файл .m! )
Это просто заставляет компилятор вычислять
NSLog()
, вместо этого расширяя ваш макрос препроцессора. Макрос ничего не делает, только удаляет аргументы.если вы хотите снова включить его, вы всегда можете использовать
Вы можете, например, просто предотвратить вызовы NSLog вокруг определенной группы методов, выполнив что-то вроде
источник
NSLog работает медленно и не должен использоваться для сборок выпуска. Простой макрос, подобный приведенному ниже, отключит его вместе со всеми возможными утверждениями, которые также следует отключить. В менее распространенном случае, когда вам нужен NSLog в сборке выпуска, просто вызовите его напрямую. Не забудьте добавить «-DNDEBUG» в настройки сборки «другие флаги c».
источник
в файле pch запишите это перед #endif
источник
как насчет этого?
источник
Это также примет дополнительные аргументы. Просто установите для параметра showDebugLogs значение true или false, в зависимости от ваших потребностей.
источник
Dlog
функции.