我正在做一个关于在Xcode中调试的演示文稿,并希望获得有关使用NSLog的更多信息.
特别是,我有两个问题:
有没有办法轻松NSLog当前方法的名称/行号?
有没有办法在编译发布代码之前轻松"禁用"所有NSLog?
diederikh.. 592
以下是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变量时输出(项目的C标志中的-DDEBUG用于调试确认).
ALog将始终输出文本(如常规NSLog).
输出(例如ALog(@"Hello world"))将如下所示:
-[LibraryController awakeFromNib] [Line 364] Hello world
whitneyland.. 141
我已经采取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
这就是它的样子:
+1 Diederik
以下是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变量时输出(项目的C标志中的-DDEBUG用于调试确认).
ALog将始终输出文本(如常规NSLog).
输出(例如ALog(@"Hello world"))将如下所示:
-[LibraryController awakeFromNib] [Line 364] Hello world
我已经采取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
这就是它的样子:
+1 Diederik
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
没有记录输出显示,但我不知道这是否有任何副作用.
这里是我们使用的一大堆调试常量.请享用.
// 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
有一个没有答案的新技巧.你可以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
我对这个问题的回答可能会有所帮助,看起来就像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
禁用所有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 !");
来自这个博客:http://whackylabs.com/rants/? p = 134
为了补充上面的答案,在某些情况下使用NSLog的替代品非常有用,尤其是在调试时.例如,删除每行上的所有日期和进程名称/ id信息可以使输出更具可读性并且更快启动.
以下链接提供了相当多的有用的弹药,使简单的日志记录更好.
http://cocoaheads.byu.edu/wiki/a-different-nslog
您可以轻松更改现有的NSLog,以显示调用它们的行号和类.在前缀文件中添加一行代码:
#define NSLog(__FORMAT__, ...) NSLog((@"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
例如,这很简单
- (void)applicationWillEnterForeground:(UIApplication*)application {
NSLog(@"%s", __PRETTY_FUNCTION__);}
输出: - [AppDelegate applicationWillEnterForeground:]
建立在上面的答案之上,这是我抄袭和想出的.还添加了内存记录.
#import#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