Suggerimento rapido personalizza NSLog per semplificare il debugging

In questo suggerimento rapido impareremo come personalizzare l'output generato da NSLog al fine di eseguire il debug dei programmi in modo più efficiente. Continuare a leggere!


Problema

Per impostazione predefinita, NSLog visualizza l'output nel seguente formato:

 Data Ora OurApp [] Uscita NSLog

Un esempio del mondo reale potrebbe assomigliare a questo:

 2013-08-03 00: 35: 53.038 TestApp [460: c07] Valore del risultato = 20

L'output di default è buono, ma lascia qualcosa a desiderare. Il più delle volte, vogliamo vedere quanto segue in una dichiarazione di registro:

  • Nome del file di origine in cui è stato chiamato NSLog ()
  • Numero di riga del codice sorgente in cui è stato chiamato NSLog ()
  • Nome della classe e metodo in cui è stato chiamato NSLog ()
  • Nascondi data e ora, nome dell'applicazione e informazioni di identificazione processo
  • Abilita / disabilita le informazioni del registro cambiando modalità (ad es. Debug, release, staging)

In breve, vorremmo che NSLog fosse più simile a questo:

 (ClassName MethodName) (SourceFileName: LineNumber) Output NSLog

Soluzione

Diamo prima un'occhiata a come NSLog funziona inalterato. NSLog è solo una funzione C integrata nel framework di base di Cocoa e si comporta come qualsiasi altra funzione C variadica. In particolare, NSLog invia messaggi di errore alla funzione Registro di sistema Apple. Lo fa semplicemente passando i suoi argomenti lungo la funzione NSLogv.

Poiché NSLog è solo un wrapper per NSLogv, possiamo ridefinire NSLog con la nostra chiamata personalizzata a NSLogv. Questo è esattamente quello che ti mostrerò come fare in questo tutorial.


1. Inizia un nuovo progetto

Crea un nuovo progetto iOS in Xcode, con il Applicazione vuota modello. Chiamalo ExtendNSLog. Controllare l'opzione per il conteggio dei riferimenti automatico, ma deselezionare le opzioni per i dati principali e i test delle unità.

Creare un progetto iOS con il modello di applicazione vuoto Il nome del prodotto dovrebbe essere "ExtendNSLog"

2. Creare una classe Objective-C

Ora crea un file di intestazione insieme al progetto. Selezionare Nuovo file> Obiettivo - Classe C. Imposta il nome della classe su ExtendNSLogFunctionality. che sarà una sottoclasse di NSObject.

Crea un modello di classe Objective - C Imposta il nome della classe su ExtendNSLogFunctionality

3. Aggiungi logica NSLog personalizzata

Passo 1

Aperto ExtendNSLogFunctionality.h e inserire il seguente codice all'interno dell'intestazione:

 #importare  #ifdef DEBUG #define NSLog (args ...) ExtendNSLog (__ FILE __, __ LINE __, __ PRETTY_FUNCTION __, args); #else #define NSLog (x ...) #endif void ExtendNSLog (const char * file, int lineNumber, const char * functionName, NSString * format, ...);

Il condizionale sopra definito definirà un NSLog dichiarazione solo quando DEBUG è definito. Quando DEBUG non è definito, l'istruzione NSLog non farà nulla. La domanda sorge spontanea: come controllate quando DEBUG è definito? Questo può essere fatto assegnando DEBUG = 1 nelle impostazioni del preprocessore per il tuo progetto.

Per fare ciò, fare clic sulla destinazione dell'applicazione e selezionare la scheda Impostazioni di creazione. Quindi assicurati che siano selezionate le opzioni "Tutto" e "Combinato". Cerca "pre-elaborazione" e individua la sezione "Macro preprocessore". Quindi, aggiungi semplicemente "DEBUG = 1" alla sezione Debug.

Aggiungi il flag DEBUG = 1 alle impostazioni del preprocessore

Si noti che nei più recenti modelli di progetto Xcode, ci sarà già una macro DEBUG = 1 definita per la configurazione di build di Debug nella sezione Macro di preprocessore. Per ulteriori informazioni, fare riferimento a questo post su StackOverflow.

Passo 2

Con la macro di debug definita, il nostro prossimo compito è scrivere la versione personalizzata di NSLog. Apri ExtendNSLogFunctionality.m e aggiungi il seguente codice:

 #import "ExtendNSLogFunctionality.h" void ExtendNSLog (const char * file, int lineNumber, const char * functionName, NSString * format, ...) // Digitare per contenere informazioni sugli argomenti delle variabili. va_list ap; // Inizializza un elenco di argomenti variabili. va_start (ap, format); // NSLog aggiunge una nuova riga alla fine del formato NSLog se // non è già presente. // Qui stiamo utilizzando questa funzione di NSLog () if (! [Format hasSuffix: @ "\ n"]) format = [format stringByAppendingString: @ "\ n"];  NSString * body = [[NSString alloc] initWithFormat: format argument: ap]; // Termina l'utilizzo dell'elenco di argomenti variabili. va_end (ap); NSString * fileName = [[NSString stringWithUTF8String: file] lastPathComponent]; fprintf (stderr, "(% s) (% s:% d)% s", functionName, [fileName UTF8String], lineNumber, [body UTF8String]); 

Passaggio 3

Aggiungere ora l'estensione ExtendNSLogFunctionality.h al file di prefisso prefisso Prefix.pch nella sezione #ifdef __OBJC__.

 #ifdef __OBJC__ #import  #importare  #import "EstendiNSLogFunctionality.h" #endif

Per una migliore comprensione delle intestazioni dei prefissi, dai un'occhiata a questa voce su Wikipedia. Per quanto riguarda le best practice sull'intestazione del prefisso, controlla questo post StackOverflow.


4. Un esempio di registro personalizzato

Ora aggiungi un NSLog ovunque nel codice del tuo progetto. Nel mio caso, decido di aggiungerne uno in -method di AppDelegate.m -Applicazione (BOOL): applicazione (UIApplication *) didFinishLaunchingWithOptions: (NSDictionary *) launchOptions.

 int result = 20; NSLog (@ "Valore del risultato:% d", risultato);

Se ora crei ed esegui il progetto con la configurazione di Debug, dovresti vedere qualcosa di simile a questo:

 (- [AppDelegate application: didFinishLaunchingWithOptions:]) (AppDelegate.m: 21) Valore del risultato: 20

Saluti! Questo output è molto più utile dell'implementazione predefinita. Spero che questa tecnica ti consenta di risparmiare un sacco di tempo mentre esegui il debug dei tuoi programmi!