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

我特别想问两个问题:

是否有一种方法可以轻松地NSLog当前方法的名称/行号? 在编译发布代码之前,是否有一种方法可以轻松地“禁用”所有nslog ?


当前回答

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

#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的有用宏:

#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

我对这个问题的回答可能会有所帮助,看起来它与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

我已经从上面取了DLog和ALog,并添加了ULog,它会引发一个UIAlertView消息。

总结:

只有当DEBUG变量被设置时,DLog才会像NSLog一样输出 ALog总是像NSLog一样输出 只有当DEBUG变量被设置时,ULog才显示UIAlertView

#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

这是它的样子:

+ 1 Diederik

禁用所有nslog,对于那些对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/

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

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

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

__FUNCTION__在c++中显示的是一个混乱的名字。__PRETTY_FUNCTION__显示的是一个很好的函数名,在cocoa中它们看起来是一样的。

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

#define NSLog

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