objective c - Come stampare il nome del metodo e il numero di riga e disabilitare NSLog in modo condizionale?




objective-c cocoa (9)

È facile modificare i NSLogs esistenti per visualizzare il numero di riga e la classe da cui vengono chiamati. Aggiungi una riga di codice al tuo file prefisso:

#define NSLog(__FORMAT__, ...) NSLog((@"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)

Sto facendo una presentazione sul debugging in Xcode e vorrei avere maggiori informazioni sull'utilizzo efficiente di NSLog.

In particolare, ho due domande:

  • c'è un modo per NSLog facilmente il nome / numero di linea del metodo corrente?
  • c'è un modo per "disabilitare" tutti NSLogs facilmente prima della compilazione per il codice di rilascio?

C'è un nuovo trucco che nessuna risposta dà. Puoi usare printf invece NSLog . Questo ti darà un registro pulito:

Con NSLog ottieni cose come questa:

2011-11-03 13:43:55.632 myApp[3739:207] Hello Word

Ma con printf si ottiene solo:

Hello World

Usa questo codice

#ifdef DEBUG
    #define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
    #define NSLog(...) {}              
#endif

Disabilitando tutti gli NSlog, per qualcuno allergico a MACROS, ecco qualcosa che puoi compilare anche:

void SJLog(NSString *format,...)
{
    if(LOG)
    {   
        va_list args;
        va_start(args,format);
        NSLogv(format, args);
        va_end(args);
    }
}

E, usalo quasi come NSLog:

SJLog(@"bye bye NSLogs !");

Da questo blog: http://whackylabs.com/rants/?p=134


Ecco alcune macro utili su NSLog che uso molto:

#ifdef DEBUG
#   define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#   define DLog(...)
#endif

// ALog always displays output regardless of the DEBUG setting
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)

La macro DLog viene utilizzata per l'output solo quando è impostata la variabile DEBUG (-DDEBUG nei flag C del progetto per la confugurazione del debug).

ALog genererà sempre il testo (come il normale NSLog).

L'output (ad esempio ALog (@ "Hello world")) sarà simile a questo:

-[LibraryController awakeFromNib] [Line 364] Hello world

Ho preso DLog e DLog dall'alto e ULog aggiunto ULog che genera un messaggio UIAlertView .

Riassumere:

  • DLog verrà emesso come NSLog solo quando è impostata la variabile DEBUG
  • ALog uscirà sempre come NSLog
  • ULog mostrerà UIAlertView solo quando è impostata la variabile DEBUG
#ifdef DEBUG
#   define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DLog(...)
#endif
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#ifdef DEBUG
#   define ULog(fmt, ...)  { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%s\n [Line %d] ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:fmt, ##__VA_ARGS__]  delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }
#else
#   define ULog(...)
#endif

Questo è quello che sembra:

+1 Diederik


La mia risposta a questa domanda potrebbe aiutare, sembra che sia simile a quello di Diederik cucinato. Si potrebbe anche voler sostituire la chiamata a NSLog() con un'istanza statica della propria classe di registrazione personalizzata, in questo modo è possibile aggiungere un flag di priorità per i messaggi di debug / warning / error, inviare messaggi a un file o database così come console, o praticamente qualsiasi altra cosa tu possa pensare.

#define DEBUG_MODE

#ifdef DEBUG_MODE
    #define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, 
              [[NSString stringWithUTF8String:__FILE__] lastPathComponent], 
              __LINE__, 
              [NSString stringWithFormat:(s), 
              ##__VA_ARGS__] )
#else
    #define DebugLog( s, ... ) 
#endif

Per completare le risposte sopra, può essere abbastanza utile utilizzare un sostituto di NSLog in determinate situazioni, specialmente quando si esegue il debug. Ad esempio, eliminare tutte le informazioni sulla data e sul nome del processo / id su ogni riga può rendere l'output più leggibile e più veloce da avviare.

Il seguente link fornisce un bel po 'di munizioni utili per rendere molto più semplice la registrazione.

http://cocoaheads.byu.edu/wiki/a-different-nslog


basandosi sulle risposte di sopra, ecco cosa ho plagiato e inventato. Aggiunta anche la registrazione di memoria.

#import <mach/mach.h>

#ifdef DEBUG
#   define DebugLog(fmt, ...) NSLog((@"%s(%d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DebugLog(...)
#endif


#define AlwaysLog(fmt, ...) NSLog((@"%s(%d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);


#ifdef DEBUG
#   define AlertLog(fmt, ...)  { \
    UIAlertView *alert = [[UIAlertView alloc] \
            initWithTitle : [NSString stringWithFormat:@"%s(Line: %d) ", __PRETTY_FUNCTION__, __LINE__]\
                  message : [NSString stringWithFormat : fmt, ##__VA_ARGS__]\
                 delegate : nil\
        cancelButtonTitle : @"Ok"\
        otherButtonTitles : nil];\
    [alert show];\
}
#else
#   define AlertLog(...)
#endif



#ifdef DEBUG
#   define DPFLog NSLog(@"%s(%d)", __PRETTY_FUNCTION__, __LINE__);//Debug Pretty Function Log
#else
#   define DPFLog
#endif


#ifdef DEBUG
#   define MemoryLog {\
    struct task_basic_info info;\
    mach_msg_type_number_t size = sizeof(info);\
    kern_return_t e = task_info(mach_task_self(),\
                                   TASK_BASIC_INFO,\
                                   (task_info_t)&info,\
                                   &size);\
    if(KERN_SUCCESS == e) {\
        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; \
        [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; \
        DebugLog(@"%@ bytes", [formatter stringFromNumber:[NSNumber numberWithInteger:info.resident_size]]);\
    } else {\
        DebugLog(@"Error with task_info(): %s", mach_error_string(e));\
    }\
}
#else
#   define MemoryLog
#endif

NSLog(@"%s %d %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);

Emette il nome del file, il numero di riga e il nome della funzione:

/proj/cocoa/cdcli/cdcli.m 121 managedObjectContext managedObjectContext

__FUNCTION__ in C ++ mostra il nome __PRETTY_FUNCTION__ mostra il nome della funzione piacevole, nel cacao hanno lo stesso aspetto.

Non sono sicuro di quale sia il modo corretto di disabilitare NSLog, l'ho fatto:

#define NSLog

E non è emerso alcun output di registrazione, tuttavia non so se questo ha effetti collaterali.





nslog