Как распечатать название метода и номер строки и условно отключить NSLog? - PullRequest
444 голосов
/ 09 июня 2009

Я делаю презентацию по отладке в Xcode и хотел бы получить больше информации об эффективном использовании NSLog.

В частности, у меня есть два вопроса:

  • Есть ли способ легко NSLog имя текущего метода / номер строки?
  • есть ли способ легко "отключить" все NSLogs перед компиляцией кода выпуска?

Ответы [ 13 ]

591 голосов
/ 09 июня 2009

Вот несколько полезных макросов вокруг NSLog, который я часто использую:

#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__)

Макрос DLog используется только для вывода, когда установлена ​​переменная DEBUG (-DDEBUG в флагах C проектов для подтверждения отладки).

ALog будет всегда выводить текст (как обычный NSLog).

Вывод (например, ALog (@ "Hello world")) будет выглядеть так:

-[LibraryController awakeFromNib] [Line 364] Hello world
141 голосов
/ 11 августа 2011

Я взял DLog и ALog сверху и добавил ULog, которое вызывает сообщение UIAlertView.

Подведем итог:

  • DLog будет выводиться как NSLog, только если переменная DEBUG установлена ​​
  • ALog всегда будет выводиться как NSLog
  • ULog будет показывать UIAlertView только когда установлена ​​переменная 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

Вот как это выглядит:

Debug UIAlertView

+ 1 Diederik

74 голосов
/ 09 июня 2009
NSLog(@"%s %d %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);

Выводит имя файла, номер строки и имя функции:

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

__FUNCTION__ в C ++ показывает искаженное имя __PRETTY_FUNCTION__ показывает хорошее имя функции, в какао они выглядят одинаково.

Я не уверен, как правильно отключить NSLog, я сделал:

#define NSLog

И никаких результатов регистрации не было обнаружено, однако я не знаю, имеет ли это какие-либо побочные эффекты.

20 голосов
/ 04 ноября 2009

Вот одна большая коллекция констант отладки, которые мы используем. Наслаждайтесь.

// Uncomment the defitions to show additional info.

//  #define DEBUG

//  #define DEBUGWHERE_SHOWFULLINFO

//  #define DEBUG_SHOWLINES
//  #define DEBUG_SHOWFULLPATH
//  #define DEBUG_SHOWSEPARATORS
//  #define DEBUG_SHOWFULLINFO


// Definition of DEBUG functions. Only work if DEBUG is defined.
#ifdef DEBUG 

    #define debug_separator() NSLog( @"────────────────────────────────────────────────────────────────────────────" );

    #ifdef DEBUG_SHOWSEPARATORS
        #define debug_showSeparators() debug_separator();
    #else
        #define debug_showSeparators()
    #endif

    /// /// /// ////// ///// 

    #ifdef DEBUG_SHOWFULLPATH
        #define debug_whereFull() debug_showSeparators(); NSLog(@"Line:%d : %s : %s", __LINE__,__FILE__,__FUNCTION__); debug_showSeparators(); 
    #else
        #define debug_whereFull() debug_showSeparators(); NSLog(@"Line:%d : %s : %s", __LINE__,[ [ [ [NSString alloc] initWithBytes:__FILE__ length:strlen(__FILE__) encoding:NSUTF8StringEncoding] lastPathComponent] UTF8String ] ,__FUNCTION__); debug_showSeparators(); 
    #endif

    /// /// /// ////// ///// 

    #define debugExt(args,...) debug_separator(); debug_whereFull(); NSLog( args, ##__VA_ARGS__); debug_separator();

    /// /// /// ////// ///// Debug Print Macros

    #ifdef DEBUG_SHOWFULLINFO
        #define debug(args,...) debugExt(args, ##__VA_ARGS__);
    #else
        #ifdef DEBUG_SHOWLINES
            #define debug(args,...) debug_showSeparators(); NSLog([ NSString stringWithFormat:@"Line:%d : %@", __LINE__, args ], ##__VA_ARGS__); debug_showSeparators();
        #else
            #define debug(args,...) debug_showSeparators(); NSLog(args, ##__VA_ARGS__); debug_showSeparators();
        #endif
    #endif

    /// /// /// ////// ///// Debug Specific Types

    #define debug_object( arg ) debug( @"Object: %@", arg );
    #define debug_int( arg ) debug( @"integer: %i", arg );
    #define debug_float( arg ) debug( @"float: %f", arg );
    #define debug_rect( arg ) debug( @"CGRect ( %f, %f, %f, %f)", arg.origin.x, arg.origin.y, arg.size.width, arg.size.height );
    #define debug_point( arg ) debug( @"CGPoint ( %f, %f )", arg.x, arg.y );
    #define debug_bool( arg )   debug( @"Boolean: %@", ( arg == YES ? @"YES" : @"NO" ) );

    /// /// /// ////// ///// Debug Where Macros

    #ifdef DEBUGWHERE_SHOWFULLINFO
        #define debug_where() debug_whereFull(); 
    #else
        #define debug_where() debug(@"%s",__FUNCTION__); 
    #endif

    #define debug_where_separators() debug_separator(); debug_where(); debug_separator();

    /// /// /// ////// /////

#else
    #define debug(args,...) 
    #define debug_separator()  
    #define debug_where()   
    #define debug_where_separators()  
    #define debug_whereFull()   
    #define debugExt(args,...)
    #define debug_object( arg ) 
    #define debug_int( arg ) 
    #define debug_rect( arg )   
    #define debug_bool( arg )   
    #define debug_point( arg )
    #define debug_float( arg )
#endif
19 голосов
/ 03 ноября 2011

Есть новый трюк, на который нет ответа. Вы можете использовать printf вместо NSLog. Это даст вам чистый журнал:

С NSLog вы получаете такие вещи:

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

Но с printf вы получите только:

Hello World

Используйте этот код

#ifdef DEBUG
    #define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
    #define NSLog(...) {}              
#endif
16 голосов
/ 09 июня 2009

Мой ответ на этот вопрос может помочь, похоже, он похож на тот, который приготовил Дидерик. Вы также можете заменить вызов на NSLog() статическим экземпляром своего собственного пользовательского класса ведения журнала, чтобы вы могли добавить флаг приоритета для сообщений отладки / предупреждений / ошибок, отправлять сообщения в файл или базу данных, а также консоль, или почти все, что вы можете придумать.

#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
13 голосов
/ 20 января 2011

Отключение всех NSLogs для людей, страдающих аллергией на MACROS, также можно скомпилировать следующим образом:

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

И используйте его почти как NSLog:

SJLog(@"bye bye NSLogs !");

Из этого блога: http://whackylabs.com/rants/?p=134

11 голосов
/ 02 марта 2013

Легко изменить существующие NSLogs для отображения номера строки и класса, из которого они вызваны Добавьте одну строку кода в файл префикса:

#define NSLog(__FORMAT__, ...) NSLog((@"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
11 голосов
/ 10 июня 2009

Чтобы дополнить ответы, приведенные выше, может быть весьма полезно использовать замену NSLog в определенных ситуациях, особенно при отладке. Например, избавление от всей информации о дате и имени процесса / идентификаторе в каждой строке может сделать вывод более читабельным и ускорить загрузку.

Следующая ссылка содержит довольно много полезных боеприпасов для упрощения регистрации.

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

6 голосов
/ 29 января 2015

Это просто, например,

- (void) applicationWillEnterForeground: (UIApplication *) application {

    NSLog(@"%s", __PRETTY_FUNCTION__);

}

Выход: - [AppDelegate applicationWillEnterForeground:]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...