Objective-C Language
логирование
Поиск…
Синтаксис
- NSLog (@ "text to log"); // Основной текстовый журнал
- NSLog (данные @:% f -% .2f ", myFloat, anotherFloat); // Ведение журнала, включая числа с плавающей запятой.
- NSLog (данные @:% i ", myInteger); // Запись текста, включая целое число.
- NSLog (данные @:% @ ", myStringOrObject); // Запись текста, ссылающегося на другой объект String или любой объект NSObject.
замечания
Для ведения журнала различных типов объектов и типов данных относятся: Objective-C, Спецификаторы формата
логирование
NSLog(@"Log Message!");
NSLog(@"NSString value: %@", stringValue);
NSLog(@"Integer value: %d", intValue);
Первый аргумент NSLog
- это NSString
содержащий формат сообщения журнала. Остальные параметры используются в качестве значений для замены вместо спецификаторов формата.
Форматирование работает точно так же, как и printf
, за исключением дополнительного спецификатора формата %@
для произвольного объекта Objective-C. Это:
NSLog(@"%@", object);
эквивалентно:
NSLog(@"%s", [object description].UTF8String);
NSLog vs printf
NSLog(@"NSLog message");
printf("printf message\n");
Выход:
2016-07-16 08:58:04.681 test[46259:1244773] NSLog message
printf message
NSLog
выводит дату, время, имя процесса, идентификатор процесса и идентификатор потока в дополнение к сообщению журнала. printf
просто выводит сообщение.
NSLog
требует NSString
и автоматически добавляет новую строку в конце. printf
требует строку C и не добавляет автоматически новую строку.
NSLog
отправляет выходные данные на stderr
, printf
отправляет выходные данные на stdout
.
Некоторые format-specifiers
в printf
vs NSLog
отличаются. Например, при включении вложенной строки возникают следующие различия:
NSLog(@"My string: %@", (NSString *)myString);
printf("My string: %s", [(NSString *)myString UTF8String]);
Формат вывода NSLog
NSLog(@"NSLog message");
Сообщение, которое печатается при вызове NSLog
имеет следующий формат при просмотре в Console.app:
Дата | Время | Название программы | ИД процесса | ИД | Сообщение | |
---|---|---|---|---|---|---|
2016-07-16 | 08:58:04.681 | test | [46259 | : | 1244773] | NSLog message |
Значения переменных журнала
Вы не должны вызывать NSLog
без строки буквенного формата следующим образом:
NSLog(variable); // Dangerous code!
Если переменная не является NSString
, программа выйдет из NSLog
, потому что NSLog
ожидает NSString
.
Если переменная является NSString
, она будет работать, если ваша строка не содержит %
. NSLog
проанализирует последовательность %
как спецификатор формата, а затем прочитает значение мусора из стека, что приведет к сбою или даже выполнению произвольного кода .
Вместо этого всегда делайте первый аргумент спецификатором формата, например:
NSLog(@"%@", anObjectVariable);
NSLog(@"%d", anIntegerVariable);
Пустое сообщение не распечатывается
Когда NSLog
предлагается печатать пустую строку, он полностью исключает журнал.
NSString *name = @"";
NSLog(@"%@", name); // Resolves to @""
Вышеприведенный код ничего не напечатает.
Хорошей практикой является префикс журналов с метками:
NSString *name = @"";
NSLog(@"Name: %@", name); // Resolves to @"Name: "
Вышеприведенный код будет печатать:
2016-07-21 14:20:28.623 App[87711:6153103] Name:
Удаление записей журнала из выпусков
Сообщения, напечатанные из NSLog
, отображаются на Console.app даже в версии сборки вашего приложения, что не имеет смысла для распечаток, которые полезны только для отладки. Чтобы исправить это, вы можете использовать этот макрос для ведения журнала отладки вместо NSLog
.
#ifdef DEBUG
#define DLog(...) NSLog(__VA_ARGS__)
#else
#define DLog(...)
#endif
Использовать:
NSString *value = @"value 1";
DLog(@"value = %@", value);
// little known fact: programmers look for job postings in Console.app
NSLog(@"We're hiring!");
В отладочных сборках DLog
вызывается NSLog
. В версиях сборки DLog
ничего не сделает.
Использование __FUNCTION __
NSLog(@"%s %@",__FUNCTION__, @"etc etc");
Вставляет имя класса и метода в вывод:
2016-07-22 12:51:30.099 loggingExample[18132:2971471] -[ViewController viewDidLoad] etc etc
Тип NSLog и BOOL
Нет спецификатора формата для печати булевого типа с использованием NSLog. Одним из способов печати логического значения является преобразование его в строку.
BOOL boolValue = YES;
NSLog(@"Bool value %@", boolValue ? @"YES" : @"NO");
Выход:
2016-07-30 22:53:18.269 Test[4445:64129] Bool value YES
Другим способом печати логического значения является передача его в целое число, достижение двоичного выхода (1 = да, 0 = нет).
BOOL boolValue = YES;
NSLog(@"Bool value %i", boolValue);
Выход:
2016-07-30 22:53:18.269 Test[4445:64129] Bool value 1
Регистрация метаданных NSLog
NSLog(@"%s %d %s, yourVariable: %@", __FILE__, __LINE__, __PRETTY_FUNCTION__, yourVariable);
Будет записывать файл, номер строки и данные функции вместе с любыми переменными, которые вы хотите зарегистрировать. Это может привести к тому, что строки журнала будут значительно длиннее, особенно с подробными именами файлов и методов, однако это может помочь ускорить диагностику ошибок.
Вы можете также обернуть это в Макро (сохранить это в Синглтон или где вам это понадобится больше всего);
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
Затем, когда вы хотите войти в систему, просто позвоните
ALog(@"name: %@", firstName);
Что даст вам что-то вроде;
-[AppDelegate application:didFinishLaunchingWithOptions:] [Line 27] name: John
Регистрация с помощью добавления в файл
NSLog хорош, но вы также можете записывать файлы, добавляя их в файл, используя код:
NSFileHandle* fh = [NSFileHandle fileHandleForWritingAtPath:path];
if ( !fh ) {
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
fh = [NSFileHandle fileHandleForWritingAtPath:path];
}
if ( fh ) {
@try {
[fh seekToEndOfFile];
[fh writeData:[self dataUsingEncoding:enc]];
}
@catch (...) {
}
[fh closeFile];
}