• Александр Черный
  • Блог
  • Проекты
  • О себе
  • RSS
24 сентября 2010

Трюки с NSLog

В мои первые дни разработки для iOS, я был вынужден сразу начать выполнять задачу, осматриваясь и осваиваясь попутно. Это хороший метод. Но можно пропустить что-то простое. Когда приложение аварийно завершилось, я не мог понять, по какой причине.

Помимо отладчика в XCode есть еще консоль (Console). Вызывается она из меню Run → Console. Или комбинацией Cmd + Shift + R. Если что-то сломалось, там можно найти сообщение об этом. Сообщения в консоль могут добавляться автоматически, например, если пытаться сделать лишний autorelease, консоль отразит этот момент. А могут добавляться и разработчиком. Делается это с помощью NSLog. Рекомендую принять к сведению и использовать.

Если приложение завершило работу аварийно, можно обратиться к iPhone Crash Reporter и посмотреть отчет в виде списка свойств в файле .crash по адресу /Library/Logs/CrashReporter.

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

Формат NSLog будет знаком всем, кто работал с printf(). Идея точно такая же: строка, определяющая формат и порядок вывода аргументов, а затем сами аргументы. В общем, это можно назвать printf() для NS и UI объектов. NSLog автоматически добавляет дату и время к выводу. Спецификатор %@ служит для вывода объекта. Большинство спецификаторов аналогичны тем, что используются в printf(). При вызове NSLog просто вызывает NSLogv, сообщая переменное число параметров.

NSLog(@"String: %@ ", aString);
NSLog(@"Float: %f ", aFloat);
NSLog(@"Integer: %i ", aInt);

Следующий код выводит имя файла, номер строки и имя функции. В C++ __FUNCTION__ показывает искаженное имя, в отличие от __PRETTY_FUNCTION__. В Cocoa между ними нет разницы.

NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);

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

#ifdef DEBUG
  #define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
  #define DLog(...)
#endif

#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

Например, ALog(@"Hello world") даст следующий результат.

-[LibraryController awakeFromNib] [Line 364] Hello world

Чтобы выключить логи по всей программе, можно прибегнуть к простому макросу.

#define NSLog
  1. Колдунства по NSLog взяты из дискуссии на Stack Overflow
  2. Еще немного про NSLog можно прочесть на CocoaDev
  3. Полный список спецификаторов из документации Apple
  4. Документация по NSLogv

objective-c   nslog   отладка   

Ваш комментарий


(не будет опубликован)


© Александр Черный, 2009–2026

Служебный вход

Работает на YAPSE, β