Objective-C Language
Logowanie
Szukaj…
Składnia
- NSLog (@ „text to log”); // Podstawowy dziennik tekstowy
- NSLog (@ "data:% f -% .2f", myFloat, anotherFloat); // Rejestrowanie tekstu, w tym liczb zmiennoprzecinkowych.
- NSLog (@ „data:% i”, myInteger); // Zapisywanie tekstu wraz z liczbą całkowitą.
- NSLog (@ "data:% @", myStringOrObject); // Rejestrowanie tekstu odnoszącego się do innego ciągu lub dowolnego obiektu pochodnego NSObject.
Uwagi
Informacje na temat rejestrowania różnych typów obiektów i typów danych można znaleźć w: Cel-C, Specyfikatory formatu
Logowanie
NSLog(@"Log Message!");
NSLog(@"NSString value: %@", stringValue);
NSLog(@"Integer value: %d", intValue);
Pierwszym argumentem NSLog
jest NSString
zawierający format komunikatu dziennika. Reszta parametrów służy jako wartości do podstawienia zamiast specyfikatorów formatu.
Formatowanie działa dokładnie tak samo jak printf
, z wyjątkiem dodatkowego specyfikatora formatu %@
dla dowolnego obiektu Objective-C. To:
NSLog(@"%@", object);
jest równa:
NSLog(@"%s", [object description].UTF8String);
NSLog vs printf
NSLog(@"NSLog message");
printf("printf message\n");
Wynik:
2016-07-16 08:58:04.681 test[46259:1244773] NSLog message
printf message
NSLog
oprócz komunikatu dziennika wyświetla datę, godzinę, nazwę procesu, identyfikator procesu i identyfikator wątku. printf
po prostu wyświetla komunikat.
NSLog
wymaga NSString
i automatycznie dodaje nowy wiersz na końcu. printf
wymaga ciągu C i nie dodaje automatycznie nowego wiersza.
NSLog
wysyła wyjście stderr
, printf
wysyła dane wyjściowe do stdout
.
Niektóre format-specifiers
w printf
vs NSLog
są różne. Na przykład przy dołączaniu zagnieżdżonego łańcucha powstają następujące różnice:
NSLog(@"My string: %@", (NSString *)myString);
printf("My string: %s", [(NSString *)myString UTF8String]);
Format wyjściowy NSLog
NSLog(@"NSLog message");
Komunikat drukowany przez wywołanie NSLog
ma następujący format, gdy jest wyświetlany w Console.app:
Data | Czas | Nazwa programu | ID procesu | ID wątku | Wiadomość | |
---|---|---|---|---|---|---|
2016-07-16 | 08:58:04.681 | test | [46259 | : | 1244773] | NSLog message |
Rejestrowanie wartości zmiennych
Nie powinieneś wywoływać NSLog
bez literalnego ciągu formatu takiego jak ten:
NSLog(variable); // Dangerous code!
Jeśli zmienna nie jest NSString
, program ulegnie awarii, ponieważ NSLog
oczekuje NSString
.
Jeśli zmienna jest ciągiem NSString
, zadziała, chyba że łańcuch zawiera %
. NSLog
sekwencję %
jako specyfikator formatu, a następnie odczytuje wartość śmieci ze stosu, powodując awarię lub nawet wykonanie dowolnego kodu .
Zamiast tego zawsze ustaw pierwszy argument jako specyfikator formatu, taki jak ten:
NSLog(@"%@", anObjectVariable);
NSLog(@"%d", anIntegerVariable);
Pusta wiadomość nie jest drukowana
Gdy NSLog
jest proszony o wydrukowanie pustego ciągu, całkowicie pomija dziennik.
NSString *name = @"";
NSLog(@"%@", name); // Resolves to @""
Powyższy kod nic nie wydrukuje.
Dobrą praktyką jest poprzedzanie dzienników etykietami:
NSString *name = @"";
NSLog(@"Name: %@", name); // Resolves to @"Name: "
Powyższy kod zostanie wydrukowany:
2016-07-21 14:20:28.623 App[87711:6153103] Name:
Usuwanie instrukcji dziennika z kompilacji wersji
Wiadomości drukowane z NSLog
są wyświetlane w Console.app nawet w kompilacji wersji aplikacji, co nie ma sensu w przypadku wydruków przydatnych tylko do debugowania. Aby to naprawić, możesz użyć tego makra do rejestrowania debugowania zamiast NSLog
.
#ifdef DEBUG
#define DLog(...) NSLog(__VA_ARGS__)
#else
#define DLog(...)
#endif
Używać:
NSString *value = @"value 1";
DLog(@"value = %@", value);
// little known fact: programmers look for job postings in Console.app
NSLog(@"We're hiring!");
W kompilacjach debugowania DLog
wywoła NSLog
. W kompilacjach wersji DLog
nic nie zrobi.
Korzystanie z __FUNKCJA __
NSLog(@"%s %@",__FUNCTION__, @"etc etc");
Wstawia nazwę klasy i metody do wyniku:
2016-07-22 12:51:30.099 loggingExample[18132:2971471] -[ViewController viewDidLoad] etc etc
Typ NSLog i BOOL
Nie ma specyfikatora formatu do drukowania typu logicznego za pomocą NSLog. Jednym ze sposobów wydrukowania wartości logicznej jest przekonwertowanie jej na ciąg.
BOOL boolValue = YES;
NSLog(@"Bool value %@", boolValue ? @"YES" : @"NO");
Wynik:
2016-07-30 22:53:18.269 Test[4445:64129] Bool value YES
Innym sposobem na wydrukowanie wartości logicznej jest rzutowanie jej na liczbę całkowitą, uzyskując wyjście binarne (1 = tak, 0 = nie).
BOOL boolValue = YES;
NSLog(@"Bool value %i", boolValue);
Wynik:
2016-07-30 22:53:18.269 Test[4445:64129] Bool value 1
Rejestrowanie metadanych NSLog
NSLog(@"%s %d %s, yourVariable: %@", __FILE__, __LINE__, __PRETTY_FUNCTION__, yourVariable);
Loguje plik, numer linii i dane funkcji wraz ze wszystkimi zmiennymi, które chcesz zarejestrować. Może to znacznie wydłużyć wiersze dziennika, szczególnie w przypadku pełnych nazw plików i metod, jednak może pomóc przyspieszyć diagnostykę błędów.
Możesz również owinąć to w Makro (przechowuj w Singleton lub tam, gdzie będzie to najbardziej potrzebne);
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
Następnie, gdy chcesz się zalogować, po prostu zadzwoń
ALog(@"name: %@", firstName);
Co da ci coś takiego;
-[AppDelegate application:didFinishLaunchingWithOptions:] [Line 27] name: John
Logowanie przez dołączenie do pliku
NSLog jest dobry, ale możesz także zalogować się, dołączając do pliku, używając kodu takiego jak:
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];
}