메소드 이름과 줄 번호를 인쇄하고 조건부로 NSLog를 비활성화하는 방법은 무엇입니까?
Xcode에서 디버깅에 대한 프레젠테이션을하고 NSLog를 효율적으로 사용하는 방법에 대한 자세한 정보를 얻고 싶습니다.
특히 두 가지 질문이 있습니다.
- 현재 메소드의 이름 / 줄 번호를 쉽게 NSLog하는 방법이 있습니까?
- 릴리스 코드를 컴파일하기 전에 모든 NSLog를 쉽게 "비활성화"하는 방법이 있습니까?
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__); #그밖에 # 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__] 메시지 : [NSString stringWithFormat : fmt , ## __ VA_ARGS__] delegate : nil cancelButtonTitle : @ "Ok"otherButtonTitles : nil]; [경고 쇼]; } #그밖에 # ULog 정의 (...) #endif
이것은 다음과 같습니다
디 데릭 +1
NSLog(@"%s %d %s %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);
파일 이름, 줄 번호 및 기능 이름을 출력합니다.
/proj/cocoa/cdcli/cdcli.m 121 managedObjectContext managedObjectContext
__FUNCTION__
C ++에서 맹 글링 된 이름 __PRETTY_FUNCTION__
은 멋진 함수 이름을 보여 주며 코코아에서는 동일하게 보입니다.
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
MACROS에 알레르기가있는 사람을 위해 모든 NSLog를 비활성화하면 다음과 같이 컴파일 할 수 있습니다.
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 <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
DLog에 새로 추가되었습니다. 릴리스 된 응용 프로그램에서 디버그를 완전히 제거하는 대신 비활성화하십시오. 사용자에게 디버깅이 필요한 문제가있는 경우 릴리스 된 애플리케이션에서 디버그 를 활성화 하고 이메일을 통해 로그 데이터를 요청 하는 방법을 알려 주십시오.
짧은 버전 : 전역 변수 (예, 게으른 간단한 솔루션)를 만들고 다음과 같이 DLog를 수정하십시오.
BOOL myDebugEnabled = FALSE;
#define DLog(fmt, ...) if (myDebugEnabled) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
Jomnius iLessons의 더 긴 답변 iLearned : 릴리스 된 응용 프로그램에서 동적 디버그 로깅을 수행하는 방법
얼마 동안 위의 몇 가지 매크로에서 채택한 매크로 사이트를 사용해 왔습니다. 제어 및 필터링 된 세부 정보를 강조하여 콘솔에 로그인하는 데 중점을 둡니다 . 많은 로그 줄을 신경 쓰지 않고 일괄 처리를 쉽게 켜고 끄려면이 유용한 방법을 찾으십시오.
먼저 위의 @Rodrigo에서 설명한 것처럼 NSLog를 printf로 선택적으로 대체합니다.
#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.
각 줄을 입력하는 데 필요한 몇 가지 추가 문자가 가치가 있음을 알았습니다.
- 전체 댓글 카테고리를 켜거나 끕니다 (예 : 모델이라고 표시된 통화 만보고).
- 더 높은 수준의 번호 또는 더 낮은 번호로 표시된 가장 중요한 통화로 세부 정보보고
많은 사람들이 이것을 약간의 과잉이라고 생각하지만 누군가가 자신의 목적에 적합하다고 생각하는 경우를 대비해서 ..
'Programing' 카테고리의 다른 글
자바 스크립트에서 문자열을 여러 구분 기호로 분리하려면 어떻게합니까? (0) | 2020.02.17 |
---|---|
주어진 두 날짜 사이의 일 수를 계산하는 방법은 무엇입니까? (0) | 2020.02.17 |
Java 리플렉션을 사용하여 개인 정적 최종 필드 변경 (0) | 2020.02.17 |
PHP의 어느 위치에서나 배열에 새 항목 삽입 (0) | 2020.02.17 |
JavaScript에서 문자열 보간을 어떻게 수행 할 수 있습니까? (0) | 2020.02.17 |