Поиск…


Синтаксис

  • 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];
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow