代码之家  ›  专栏  ›  技术社区  ›  rein

如何打印出方法名称和行号,并有条件地禁用NSLog?

  •  451
  • rein  · 技术社区  · 16 年前

    • 在编译发布代码之前,有没有一种方法可以轻松地“禁用”所有NSLogs?
    13 回复  |  直到 9 年前
        1
  •  587
  •   diederikh    13 年前

    以下是我经常使用的关于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__)
    

    ALog将始终输出文本(与常规NSLog一样)。

    输出(例如ALog(@“Hello world”))如下:

    -[LibraryController awakeFromNib] [Line 364] Hello world
    
        2
  •  141
  •   Sujay DÅ©ng Nguyễn    10 年前

    DLog ALog ULog UIAlertView

    总结一下:

    • DLog NSLog 仅当设置了DEBUG变量时
    • ALog 将始终输出如下
    • 用户日志 将显示 仅当设置了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

        3
  •  74
  •   Ben Clayton    13 年前
    NSLog(@"%s %d %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);
    

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

    __FUNCTION__ 在C++中显示损坏的名称 __PRETTY_FUNCTION__ 显示了很好的函数名称,在可可中它们看起来是一样的。

    #define NSLog
    

    没有显示日志输出,但我不知道这是否有任何副作用。

        4
  •  20
  •   SEQOY Development Team    16 年前

    // 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
    
        5
  •  19
  •   Rodrigo    13 年前

    printf 相反 NSLog 。这将为您提供一个干净的日志:

    随着 你会得到这样的东西:

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

    但是随着 输出函数

    Hello World
    

    #ifdef DEBUG
        #define NSLog(FORMAT, ...) fprintf(stderr,"%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
    #else
        #define NSLog(...) {}              
    #endif
    
        6
  •  16
  •   Community Mohan Dere    8 年前

    this question 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
    
        7
  •  13
  •   Refactor    13 年前

    禁用所有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 !");
    

    从这个博客: https://whackylabs.com/logging/ios/2011/01/19/ios-moving-in-and-out-of-nslogs/

        9
  •  11
  •   AddisDev    13 年前

    更改现有的NSLogs以显示调用它们的行号和类很容易。在前缀文件中添加一行代码:

    #define NSLog(__FORMAT__, ...) NSLog((@"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
    
        10
  •  6
  •   Venkat Reddy    11 年前

    例如,这很简单

        NSLog(@"%s", __PRETTY_FUNCTION__);
    

    }

    输出: -[AppDelegate应用程序将进入前台:]

        11
  •  5
  •   Dickey Singh    13 年前

    在上述答案的基础上,以下是我抄袭并得出的结论。还添加了内存日志记录。

    #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
    
        12
  •  4
  •   JOM agenthunt    14 年前

    DLog的新增功能。不要从已发布的应用程序中完全删除调试,只需禁用它。当用户遇到需要调试的问题时,只需告诉如何

    BOOL myDebugEnabled = FALSE;
    #define DLog(fmt, ...) if (myDebugEnabled) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
    

    Jomnius iLessons iLearned的更长答案: How to Do Dynamic Debug Logging in Released Application

        13
  •  3
  •   cate    12 年前

    一段时间以来,我一直在使用一个采用了上述几个宏的网站。我的重点是在控制台中登录,重点是 ;如果你不介意很多日志行,但想轻松地切换它们的批次;关闭后,您可能会发现这很有用。

    #define NSLOG_DROPCHAFF//comment out to get usual date/time ,etc:2011-11-03 13:43:55.632 myApp[3739:207] Hello Word
    
    #ifdef NSLOG_DROPCHAFF
    #define NSLog(FORMAT, ...) printf("%s\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
    #endif
    

    接下来,我打开或关闭登录。

    #ifdef DEBUG
    #define LOG_CATEGORY_DETAIL// comment out to turn all conditional logging off while keeping other DEBUG features
    #endif
    

    分类 超过该值将不会调用日志记录调用。然后定义各种 风味 NSLog输出

    #ifdef LOG_CATEGORY_DETAIL
    
        //define the categories using bitwise leftshift operators
        #define kLogGCD (1<<0)
        #define kLogCoreCreate (1<<1)
        #define kLogModel (1<<2)
        #define kLogVC (1<<3)
        #define kLogFile (1<<4)
        //etc
    
        //add the categories that should be logged...
        #define kLOGIFcategory kLogModel+kLogVC+kLogCoreCreate
    
        //...and the maximum detailLevel to report (use -1 to override the category switch)
        #define kLOGIFdetailLTEQ 4
    
        // output looks like this:"-[AppDelegate myMethod] log string..."
        #   define myLog(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((@"%s " format), __PRETTY_FUNCTION__, ##__VA_ARGS__);}
    
        // output also shows line number:"-[AppDelegate myMethod][l17]  log string..."
        #   define myLogLine(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((@"%s[l%i] " format), __PRETTY_FUNCTION__,__LINE__ ,##__VA_ARGS__);}
    
        // output very simple:" log string..."
        #   define myLogSimple(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((@"" format), ##__VA_ARGS__);}
    
        //as myLog but only shows method name: "myMethod: log string..."
        // (Doesn't work in C-functions)
        #   define myLog_cmd(category,detailLevel,format,...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((@"%@: " format), NSStringFromSelector(_cmd), ##__VA_ARGS__);}
    
        //as myLogLine but only shows method name: "myMethod>l17: log string..."
        #   define myLog_cmdLine(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((@"%@>l%i: " format), NSStringFromSelector(_cmd),__LINE__ , ##__VA_ARGS__);}
    
        //or define your own...
       // # define myLogEAGLcontext(category,detailLevel,format, ...) if(detailLevel<0 || ((category&kLOGIFcategory)&&detailLevel<= kLOGIFdetailLTEQ)) {NSLog((@"%s>l%i (ctx:%@)" format), __PRETTY_FUNCTION__,__LINE__ ,[EAGLContext currentContext], ##__VA_ARGS__);}
    
    #else
        #   define myLog_cmd(...)
        #   define myLog_cmdLine(...)
        #   define myLog(...)
        #   define myLogLine(...)
        #   define myLogSimple(...)
        //#   define myLogEAGLcontext(...)
    #endif
    

    因此,根据kLOGIFcategory和kLOGIFdetailLTEQ的当前设置,调用类似

    myLogLine(kLogVC, 2, @"%@",self);
    

    myLogLine(kLogGCD, 2, @"%@",self);//GCD not being printed
    

    myLogLine(kLogGCD, 12, @"%@",self);//level too high
    

    myLogLine(kLogGCD, -2, @"%@",self);//now printed even tho' GCD category not active.
    

    我相信很多人会觉得这有点矫枉过正,但以防万一有人发现这符合他们的目的。。

    推荐文章