Hurtig Tips Tilpass NSLog for enklere feilsøking

I dette raske tipset skal vi lære å tilpasse produksjonen som genereres av NSLog for å feilsøke programmer mer effektivt. Les videre!


Problem

NSLog viser som standard utdata i følgende format:

 Dato Tid OurApp [] NSLog-utgang

Et ekteeksempel kan se slik ut:

 2013-08-03 00: 35: 53.038 TestApp [460: c07] Verdi av resultatet = 20

Standardutgangen er god, men det etterlater noe å være ønsket. Mesteparten av tiden ønsker vi å se følgende i en loggoppføring:

  • Navn på kildefilen der NSLog () ble kalt
  • Kildekode linjenummer der NSLog () ble kalt
  • Navn på klassen og metoden der NSLog () ble kalt
  • Skjul dato klokkeslett, programnavn og prosess id info
  • Aktiver / deaktiver logginformasjon ved å endre modus (for eksempel feilsøking, utgivelse, oppstart)

Kort sagt, vi vil at NSLog skal være mer slik:

 (ClassName MethodName) (SourceFileName: LineNumber) NSLog-utgang

Løsning

La oss først se på hvordan NSLog fungerer uendret. NSLog er bare en C-funksjon som er bygd inn i grunnlaget for kakao, og oppfører seg akkurat som enhver annen variadisk C-funksjon. Spesielt sender NSLog feilmeldinger til Apple System Log-anlegget. Det gjør dette ved å overføre sine argumenter til NSLogv-funksjonen.

Fordi NSLog er bare en wrapper for NSLogv, kan vi omdefinere NSLog med vårt eget tilpassede anrop til NSLogv. Det er akkurat det jeg skal vise deg hvordan du gjør i denne opplæringen.


1. Start et nytt prosjekt

Opprett et nytt iOS-prosjekt i Xcode, med Tom søknad mal. Kall det ExtendNSLog. Kontroller alternativet for Automatisk referansetelling, men fjern merket for valgene for Core Data og Unit Tests.

Opprett et iOS-prosjekt med den tomme applikasjonsmalen Produktnavn skal være "ExtendNSLog"

2. Lag en mål-C klasse

Opprett nå en headerfil sammen med prosjektet. Å velge Ny fil> Mål - C klasse. Angi navnet på klassen til ExtendNSLogFunctionality. som vil være en underklasse av NSObject.

Lag en objektiv - C-klasse mal Sett klassenavnet til ExtendNSLogFunctionality

3. Legg til tilpasset NSLog Logic

Trinn 1

Åpen ExtendNSLogFunctionality.h og legg inn følgende kode i overskriften:

 #importere  #ifdef DEBUG #define NSLog (args ...) ExtendNSLog (__ FIL __, __ LINE __, __ PRETTY_FUNCTION __, args); #else #define NSLog (x ...) #endif void ExtendNSLog (const char * fil, int lineNumber, const char * funksjonnavn, NSString * format, ...);

Ovennevnte betingede vilje definerer en NSLog setning bare når DEBUG er definert. Når DEBUG ikke er definert, vil NSLog-setningen ikke gjøre noe. Spørsmålet oppstår: Hvordan kontrollerer du når DEBUG er definert? Dette kan gjøres ved å tildele DEBUG = 1 i preprosessorinnstillingene for prosjektet.

For å gjøre det, klikk på søknadsmålet ditt, og velg fanen Bygg innstillinger. Deretter må du kontrollere at alternativene "Alle" og "Kombinert" er valgt. Søk etter "preprocessing" og finn avsnittet "Preprocessor Macros". Deretter legger du ganske enkelt til "DEBUG = 1" til Debug-delen.

Legg til DEBUG = 1-flagget til preprosessorinnstillingene

Legg merke til at i nyere Xcode-prosjektmaler vil det allerede være en DEBUG = 1-makro definert for Debug-byggekonfigurasjonen i delen Preprocessor Macros. For mer informasjon, se dette innlegget på StackOverflow.

Steg 2

Med feilsøkingsmakroen definert, er vår neste oppgave å skrive den egendefinerte versjonen av NSLog. Åpne ExtendNSLogFunctionality.m og legg til følgende kode:

 #import "ExtendNSLogFunctionality.h" void ExtendNSLog (const char * fil, int lineNumber, const char * funksjonnavn, NSString * format, ...) // Type for å holde informasjon om variable argumenter. va_list ap; // Initialiser en variabel argumentliste. va_start (ap, format); // NSLog legger bare til en ny linje til slutten av NSLog-formatet hvis // en ikke allerede er der. // Her bruker vi denne funksjonen til NSLog () hvis (! [Format hasSuffix: @ "\ n"]) format = [format stringByAppendingString: @ "\ n"];  NSString * body = [[NSString alloker] initWithFormat: format argumenter: ap]; // Slutt ved hjelp av variabel argumentliste. va_end (ap); NSString * fileName = [[NSString stringWithUTF8String: fil] lastPathComponent]; fprintf (stderr, "(% s) (% s:% d)% s", funksjonsnavn, [filnavn UTF8String], lineNumber, [body UTF8String]); 

Trinn 3

Nå legger du til ExtendNSLogFunctionality.h inkluderer til prefiksheaderfilen Prefix.pch i avsnittet #ifdef __OBJC__.

 #ifdef __OBJC__ #import  #importere  #import "ExtendNSLogFunctionality.h" #endif

For en bedre forståelse av prefikshoder, ta en titt på denne oppføringen på Wikipedia. Når det gjelder prefikshodepraksis, sjekk ut dette StackOverflow-innlegget.


4. Et egendefinert loggeksempel

Legg nå en NSLog hvor som helst i prosjektkoden din. I mitt tilfelle velger jeg å legge til en i AppDelegate.ms metode -(BOOL) søknad: (UIApplication *) søknad didFinishLaunchingWithOptions: (NSDictionary *) launchOptions.

 int resultat = 20; NSLog (@ "Verdi av resultat:% d", resultat);

Hvis du bygger og kjører prosjektet med Debug-konfigurasjonen nå, bør du se noe slikt:

 (- [AppDelegate søknad: didFinishLaunchingWithOptions:]) (AppDelegate.m: 21) Verdi av resultatet: 20

Jubel! Denne utdataen er mye mer nyttig enn standardimplementeringen. Forhåpentligvis finner du at denne teknikken vil spare deg mye tid mens du feilsøker dine egne programmer!