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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/969130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:41:35  来源:igfitidea点击:

How to print out the method name and line number and conditionally disable NSLog?

objective-ccocoacocoa-touchxcodenslog

提问by rein

I'm doing a presentation on debugging in Xcode and would like to get more information on using NSLog efficiently.

我正在做一个关于在 Xcode 中调试的演示,并希望获得有关有效使用 NSLog 的更多信息。

In particular, I have two questions:

特别是,我有两个问题:

  • is there a way to easily NSLog the current method's name / line number?
  • is there a way to "disable" all NSLogs easily before compiling for release code?
  • 有没有办法轻松 NSLog 当前方法的名称/行号?
  • 有没有办法在编译发布代码之前轻松“禁用”所有 NSLogs?

回答by diederikh

Here are some useful macros around NSLog I use a lot:

这里有一些关于 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__)

The DLog macro is used to only output when the DEBUG variable is set (-DDEBUG in the projects's C flags for the debug confirguration).

DLog 宏仅用于在设置 DEBUG 变量时输出(项目的 C 标志中的 -DDEBUG 用于调试配置)。

ALog will always output text (like the regular NSLog).

ALog 将始终输出文本(就像常规的 NSLog)。

The output (e.g. ALog(@"Hello world") ) will look like this:

输出(例如 ALog(@"Hello world") )将如下所示:

-[LibraryController awakeFromNib] [Line 364] Hello world

回答by whitneyland

I've taken DLogand ALogfrom above, and added ULogwhich raises a UIAlertViewmessage.

我已经从上面获取了DLogALog,并添加了ULog它引发了一条UIAlertView消息。

To summarize:

总结一下:

  • DLogwill output like NSLogonly when the DEBUG variable is set
  • ALogwill always output like NSLog
  • ULogwill show the UIAlertViewonly when the DEBUG variable is set
  • DLogNSLog仅在设置了 DEBUG 变量时才会输出
  • ALog总是会输出像 NSLog
  • ULogUIAlertView仅在设置了 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

This is what it looks like:

这是它的样子:

Debug UIAlertView

调试 UIAlertView

+1 Diederik

+1 迪德里克

回答by stefanB

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

Outputs file name, line number, and function name:

输出文件名、行号和函数名:

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

__FUNCTION__in C++ shows mangled name __PRETTY_FUNCTION__shows nice function name, in cocoa they look the same.

__FUNCTION__在 C++ 中显示损坏的名称__PRETTY_FUNCTION__显示了不错的函数名称,在可可中它们看起来相同。

I'm not sure what is the proper way of disabling NSLog, I did:

我不确定禁用 NSLog 的正确方法是什么,我做了:

#define NSLog

And no logging output showed up, however I don't know if this has any side effects.

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

回答by SEQOY Development Team

Here one big collection of debug constants that we use. Enjoy.

这是我们使用的一大堆调试常量。享受。

// 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

回答by Rodrigo

There are a new trick that no answer give. You can use printfinstead NSLog. This will give you a clean log:

有一个没有答案的新技巧。您可以printf改用NSLog. 这会给你一个干净的日志:

With NSLogyou get things like this:

随着NSLog你得到这样的事情:

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

But with printfyou get only:

printf你只会得到:

Hello World

Use this code

使用此代码

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

回答by Marc Charbonneau

My answer to this questionmight help, looks like it's similar to the one Diederik cooked up. You may also want to replace the call to NSLog()with a static instance of your own custom logging class, that way you can add a priority flag for debug/warning/error messages, send messages to a file or database as well as the console, or pretty much whatever else you can think of.

我对这个问题的回答可能会有所帮助,看起来它类似于 Diederik 制作的那个。您可能还想将调用替换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

回答by chunkyguy

Disabling all NSLogs, for somebody allergic to MACROS, here is something that you can compile too:

禁用所有 NSLogs,对于对 MACROS 过敏的人,这里有一些你也可以编译的东西:

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

And, use it almost like NSLog:

并且,几乎像 NSLog 一样使用它:

SJLog(@"bye bye NSLogs !");

From this blog: https://whackylabs.com/logging/ios/2011/01/19/ios-moving-in-and-out-of-nslogs/

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

回答by Quinn Taylor

To complement the answers above, it can be quite useful to use a replacement for NSLog in certain situations, especially when debugging. For example, getting rid of all the date and process name/id information on each line can make output more readable and faster to boot.

为了补充上面的答案,在某些情况下使用 NSLog 的替代品非常有用,尤其是在调试时。例如,去掉每一行上的所有日期和进程名称/id 信息可以使输出更具可读性和更快的启动。

The following link provides quite a bit of useful ammo for making simple logging much nicer.

以下链接提供了相当多有用的弹药,可让简单的日志记录变得更好。

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

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

回答by AddisDev

It's easy to change your existing NSLogs to display line number and class from which they are called. Add one line of code to your prefix file:

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

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

回答by Venkat Reddy

It is simple,for Example

这很简单,例如

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

    NSLog(@"%s", __PRETTY_FUNCTION__);

}

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

    NSLog(@"%s", __PRETTY_FUNCTION__);

}

Output:-[AppDelegate applicationWillEnterForeground:]

输出:-[AppDelegate applicationWillEnterForeground:]