我正在做一个关于在Xcode中调试的演示,想要获得更多关于有效使用NSLog的信息。
我特别想问两个问题:
是否有一种方法可以轻松地NSLog当前方法的名称/行号? 在编译发布代码之前,是否有一种方法可以轻松地“禁用”所有nslog ?
我正在做一个关于在Xcode中调试的演示,想要获得更多关于有效使用NSLog的信息。
我特别想问两个问题:
是否有一种方法可以轻松地NSLog当前方法的名称/行号? 在编译发布代码之前,是否有一种方法可以轻松地“禁用”所有nslog ?
当前回答
一段时间以来,我一直在使用上面几个宏的站点。我的重点是登录控制台,重点是控制和过滤的冗长;如果您不介意大量的日志行,但想要轻松地开关它们的批量,那么您可能会发现这很有用。
首先,我可以选择用上面@Rodrigo所描述的printf替换NSLog
#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.
我发现每行多打几个字是值得的
打开或关闭整个评论类别(例如,只报告那些标记为Model的调用) 报告细节时使用较高级别的数字,或者只报告最重要的电话时使用较低的数字
我相信很多人会觉得这有点过分,但以防有人发现它适合他们的目的。
其他回答
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
并且没有日志输出显示,但是我不知道这是否有任何副作用。
这是一个没有答案的新把戏。你可以用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
一段时间以来,我一直在使用上面几个宏的站点。我的重点是登录控制台,重点是控制和过滤的冗长;如果您不介意大量的日志行,但想要轻松地开关它们的批量,那么您可能会发现这很有用。
首先,我可以选择用上面@Rodrigo所描述的printf替换NSLog
#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.
我发现每行多打几个字是值得的
打开或关闭整个评论类别(例如,只报告那些标记为Model的调用) 报告细节时使用较高级别的数字,或者只报告最重要的电话时使用较低的数字
我相信很多人会觉得这有点过分,但以防有人发现它适合他们的目的。
我已经从上面取了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
这很简单,举个例子
-(void) applicationwillenter前台:(UIApplication *)application { NSLog(@“% s”,__PRETTY_FUNCTION__); }
输出: - - - - - - [AppDelegate applicationWillEnterForeground:]