Техническое примечание TN2347

Основная отладка с NSLog функционирует и макрос препроцессора DEBUG

Отображение сообщений журнала в системной консоли при запуске приложения является одним из самых старых доступных механизмов отладки. Используя журналирование, можно генерировать копию, описывающую операции, выполняемые заявлением, которое можно рассмотреть еще долго после того, как приложение закончило работать. Кроме того, в то время как Ваше приложение работает, можно наблюдать сообщения журнала, сгенерированные и записанные в консоль как события в приложении, которое они описывают, имеют место. Как разработчик, Вы полностью управляете текстом и информацией, выведенной на экран в консоли NSLog. Журналирование может показать даже самое жесткое для нахождения проблем в приложении.

Этот документ говорит о практических соображениях о NSLog функционируйте и макрос препроцессора DEBUG, которые полезны для отладки.

Вот пример какой вызов к NSLog похож:

NSString *message = @"test message";
 
NSLog( @"Here is a test message: '%@'", message );

и для вышеупомянутого оператора консольный вывод появился бы следующим образом:

Here is a test message: 'test message'

Это действительно просто настолько просто! И в этой точке в этом документе у Вас теперь есть достаточно информации, чтобы начать использовать NSLog отладить Ваше приложение. Но, необходимо продолжать продолжать читать: остаток от этого документа добавляет дополнительные подробные данные, которые можно использовать, чтобы уполномочить себя использовать журналирование эффективнее в Ваших проектах.

Этот документ является подходящим для всего iOS и разработчиков OS X. Это предполагает, что читатель использует XCode, познакомился с языком Objective C и понимает основы использования препроцессора языка C.

Где найти вывод NSLOG
Как вызвать NSLog
Хорошие вещи включать в Ваши журналы
Макрос препроцессора DEBUG
Больше лучше, действительно
NSLog является общим другом
Дополнительные ресурсы.
История версии документа

Где найти вывод NSLOG

Платформа Основы NSLog функция доступна в каждой версии когда-либо поставлявшего iOS и OS X. Также, можно полагаться на него являющийся доступным в целях отладки на любой платформе Apple, куда будет работать приложение. NSLog выводы обмениваются сообщениями к Системному средству Журнала Apple или к Консольному приложению (обычно снабжаемый префиксом время и ID процесса). Многое из системного использования платформ NSLog для журналирования исключений и ошибок, но нет никакого требования для ограничения его использования теми целями. Также совершенно приемлемо использовать NSLog для вывода значений переменных, параметров, функциональных результатов, отслеживаний стека и другой информации, таким образом, Вы видите то, что происходит в Вашем коде во время выполнения.

Вывод Console может появиться во многих местах включая (но не ограничиваясь этим) XCode и Консольное приложение. Для получения дополнительной информации о нахождении консольного вывода от вызовов Вашего приложения до NSLog, посмотрите Технические Вопросы и ответы QA1747: Отладка Развернутых приложений для iOS.

Как вызвать NSLog

Платформа Основы NSLog функция работает точно так же, как стандартная библиотека для C printf функция, большая разница, являющаяся, что строка формата указана как»NSString *«введенное значение вместо строки C-стиля.

Простой пример

Вот пример, показывающий, как вызвать NSLog:

NSString *outputData = @"A quick brown fox jumps over a lazy dog!";
 
NSLog( @"text: %@", outputData );
 
/* Comment:
 
    @"text: %@" - is the printf style formatting template for output (an NSString *)
 
    outputData - refers to to the text we wish to display (also an NSString *)
 
*/

И, вот то, как появится вывод:

text: A quick brown fox jumps over a lazy dog!

Усовершенствованные подробные данные

Определение для NSLog функция появляется следующим образом:

void NSLog(NSString *format, ...);

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

Как printf функция, NSLog маркеры замены использования; однако, существует один дополнительный маркер замены, доступный в Objective C, %@, используемый, чтобы указать, что его соответствующий параметр должен быть объектом Objective C.

В дополнение к %@ маркер замены, весь постоянный клиент printf маркеры замены стиля доступны для Вашего использования. Для получения дополнительной информации о маркерах замены, используемых NSLog посмотрите раздел «String Format Specifiers» «Строкового Руководства по программированию».

Хорошие вещи включать в Ваши журналы

Журналирование позволяет Вам создавать копию, описывающую работу Вашего приложения, которое можно позже проанализировать на досуге. Также, Вы хотите включать как можно больше полезной информации в свои журналы так, чтобы для Вас было проще действительно видеть то, что происходит как Ваше выполнение приложения. Вот некоторые элементы, обычно включающиеся в журналы с некоторым объяснением:

Логика и ветвление

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

Уникальный и простой найти текстовые образцы

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

Значения переменных и значения свойств

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

В дополнение к %@ маркер замены, весь постоянный клиент printf маркеры замены стиля могут использоваться в строке форматирования. Это позволит Вам отображать много различных видов значений. Для получения дополнительной информации о маркерах замены, которые могут использоваться с NSLog посмотрите раздел «String Format Specifiers» «Строкового Руководства по программированию».

double myNumber = 7.7;
NSLog(@"number: %@", @(myNumber));

Распечатает:

number: 7.7

Этот метод работает со всеми числовыми типами, о которых компилятор знает (целое число со знаком или целое без знака или числа с плавающей точкой любого размера - 8, 16, 32 или 64 бита), и будут любые необходимые приведения типа для Вас, не генерируя предупреждений компилятора.

Кого вызывают?

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

- (void)pressButton:(id)sender
{
    NSLog( @"calling: %s", __PRETTY_FUNCTION__ );
    ....

Здесь, предопределенная переменная времени компиляции __PRETTY_FUNCTION__ (строка стиля C), используется для печати имени вызванной функции. Этот метод особенно полезен, когда Вы анализируете код с помощью большого количества делегатов, и требуется понять последовательность, в которой вызовы выполняются к методам делегата.

Вышеупомянутое распечатает следующее в консоли:

calling: -[MyObjectClassName pressButton:]

Зарегистрируйте след своего штабеля!

При исследовании крешлогов след штабеля неоценим для выяснения цепи событий, приведшей к любому определенному обстоятельству. При использовании NSLog для отладки можно получить копию текущего следа штабеля в любое время путем вызова NSThread -callStackSymbols метод класса. След возвращается как NSArray из строк и можно использовать NSLog вместе с %@ маркер замены для вывода следа к консоли:

NSLog(@"%@", [NSThread callStackSymbols]);

И, вот пример того, на что похож вывод вышеупомянутого оператора:

2014-04-30 18:44:30.075 AVCustomEdit[52779:60b] (
 0  AVCustomEdit      0x0000efa6 -[APLSimpleEditor buildCompositionObjectsForPlayback:] + 278
 1  AVCustomEdit      0x0000686e -[APLViewController viewDidAppear:] + 590
 2  UIKit             0x007a4099 -[UIViewController _setViewAppearState:isAnimating:] + 526
 3  UIKit             0x007a4617 -[UIViewController __viewDidAppear:] + 146
 4  UIKit             0x007a49aa -[UIViewController _executeAfterAppearanceBlock] + 63
 5  UIKit             0x0069f0d0 ___afterCACommitHandler_block_invoke_2 + 33
 6  UIKit             0x0069f055 _applyBlockToCFArrayCopiedToStack + 403
 7  UIKit             0x0069ee9a _afterCACommitHandler + 568
 8  CoreFoundation    0x029db2bf __CFRunLoopDoObservers + 399
 9  CoreFoundation    0x029b9254 __CFRunLoopRun + 1076
 10 CoreFoundation    0x029b89d3 CFRunLoopRunSpecific + 467
 11 CoreFoundation    0x029b87eb CFRunLoopRunInMode + 123
 12 GraphicsServices  0x0318b5ee GSEventRunModal + 192
 13 GraphicsServices  0x0318b42b GSEventRun + 104
 14 UIKit             0x00681f9b UIApplicationMain + 1225
 15 AVCustomEdit      0x000026bd main + 141
 16 libdyld.dylib     0x0269e701 start + 1
)

Макрос препроцессора DEBUG

Короче говоря макрос процессора DEBUG действует как переключатель, который можно использовать для включения от различных разделов кода. В частности макрос DEBUG предназначается, чтобы использоваться для включения и выключения различных разделов исходного кода, связанного с отладкой. XCode, по умолчанию, включает определение для макроса DEGUG, установленного в 1 для сборок отладки и 0 для сборок конечных версий. И, можно использовать в своих интересах это для автоматического включения дополнительной отладки и журналирования кода в сборках отладки.

Вот пример, показывающий, как может использоваться макрос DEBUG:

- (void)pressButton:(id)sender
{
#if DEBUG
    NSLog(@"preparing to press button!");
#endif
    [self prepareForButtonPress];
 
#if DEBUG
    NSLog(@"pressing button!");
#endif
 
    [self activatePressButtonSequence:self withCompletion:^{
#if DEBUG
        NSLog(@"button sequence complete.");
#endif
            [self buttonPowerDown];
        }];
    NSLog(@"This line has no DEBUG macro, so it gets printed in both debug and release builds!");
}

Отладочная сборка (с DEBUG == 1) произведет следующий вывод в консоли:

preparing to press button!
pressing button!
button sequence complete.
This line has no DEBUG macro, so it gets printed in both debug and release builds!

Сборка конечных версий (с DEBUG == 0) произведет следующий вывод в консоли:

This line has no DEBUG macro, so it gets printed in both debug and release builds!

Макрос препроцессора DEBUG в XCode

Препроцессор макрос «DEBUG» определяется во всех шаблонах проекта XCode для сборок отладки. Макросы препроцессора интерпретируются во время компиляции, и макрос препроцессора DEBUG может использоваться, чтобы позволить коду отладки быть выполненным в сборках отладки Вашего проекта. Если Вы не уверены, что Вашему проекту определили его, можно проверить, что это это путем выбора проекта в XCode и щелчка по вкладке настроек сборки. Поиск Предварительной обработки и удостоверяется, что DEBUG=1 определяется для Ваших сборок отладки (как показано рев). Если это уже не определяется в Вашем проекте, можно добавить его. Макросы препроцессора чувствительны к регистру.

Рисунок 1  макрос препроцессора DEBUG, устанавливающий в проекте XCode.

Больше лучше, действительно

Если Вы отлаживаете свое приложение, и Вы добавили журналирование, но Вы продолжаете ускользнуться проблемой, которую Вы пытаетесь найти, то Вы не добавили достаточно журналирования. Продолжайте добавлять журналирование к своему приложению, пока Вы не в состоянии получить достаточно информации, таким образом, Вы в состоянии понять то, что происходит.

NSLog является общим другом

Каждый разработчик iOS или OS X, который Вы будете когда-либо встречаться, вероятно, встретился NSLog в какой-то момент. И, у разработчиков, которых Вы знаете, могут быть некоторые интересные идеи о том, как использовать его, который может быть полезным для Вас. Если у Вас есть какие-либо дополнительные вопросы о NSLog или нуждаюсь в помощи с отладкой, задайте свои вопросы в надлежащем Mac или разделах отладки Форумов Разработчика iOS. Если у Вас есть какая-либо обратная связь об этом документе, представьте его с помощью вкладки Feedback у основания документа.

Дополнительные ресурсы.



История версии документа


ДатаПримечания
14.05.2014

Новый документ, говорящий об основной отладке с помощью функции NSLog и макроса препроцессора «DEBUG».