programing

메서드 이름과 행 번호를 출력하여 NSLog를 조건부로 비활성화하려면 어떻게 해야 합니까?

minimums 2023. 4. 18. 21:58
반응형

메서드 이름과 행 번호를 출력하여 NSLog를 조건부로 비활성화하려면 어떻게 해야 합니까?

Xcode 디버깅에 대한 프레젠테이션을 하고 있는데 NSLog를 효율적으로 사용하는 방법에 대해 자세히 알고 싶습니다.

특히 두 가지 질문이 있습니다.

  • 현재 메서드의 이름/라인 번호를 쉽게 NSLogg 할 수 있는 방법이 있습니까?
  • 릴리스 코드를 컴파일하기 전에 모든 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위, from, 리, 리, 리, from, from, from, from, from, from, from을 추가ULog에, 「이러다」라고 하는 것은,UIAlertView★★★★★★★★★★★★★★★★★★.

요약:

  • DLog됩니다.NSLog가 DEBUG로 되어 있는
  • ALog항상 다음과 같이 출력됩니다.NSLog
  • ULog 해서 보여드릴게요.UIAlertView가 DEBUG로 되어 있는
#ifdef 디버깅# DLog(fmt, ...) NSLog(@"%s [Line %d] "fmt", __PRITY_FUNTION__, __LINE__, ##_VA_)를 정의합니다.ARGS__);#실패하다# DLog 정의(...))#엔디프#정의 ALog(fmt, ...) NSLog(@"%s [Line %d] "fmt", __PRITY_FUNTION__, __LINE__, ##_VA_)ARGS__);#ifdef 디버깅# 정의 ULog(fmt, ...) {UIAlertView*loc = [[UIAlertViewallocate] initWithTitle:[NSString 문자열 WithFormat:@"%s\n [Line %d]", __PRITY_FUNTION__, __LINE__]메시지:[NSString 문자열 WithFormat: fmt, ##_VA_]ARGS__] 대리자:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [경고쇼]; }#실패하다# ULog(...)를 정의합니다.)#엔디프

다음과 같이 표시됩니다.

UIAlert View 디버깅

+1 디데릭

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

파일명, 회선번호 및 함수명을 출력합니다.

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

__FUNCTION__C에서는, 이름이 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

질문에 대한 제 답변이 도움이 될 것 같아요. 디데릭이 요리한 것과 비슷한 것 같아요.콜을 다음 주소로 교환할 수도 있습니다.NSLog()커스텀 로깅클래스의 스태틱인스턴스를 사용하면 디버깅/경고/오류 메시지의 priority 플래그를 추가하거나 콘솔뿐만 아니라 파일 또는 데이터베이스로 메시지를 보내거나 기타 생각할 수 있는 거의 모든 것을 추가할 수 있습니다.

#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를 비활성화하면 다음과 같이 컴파일할 수 있습니다.

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

NSLog와 거의 동일하게 사용합니다.

SJLog(@"bye bye NSLogs !");

블로그에서 :

위의 답변을 보완하기 위해 특정 상황에서 특히 디버깅 시 NSLog 대체를 사용하면 매우 유용합니다.예를 들어, 각 행의 날짜 및 프로세스 이름/ID 정보를 모두 삭제하면 출력을 보다 읽기 쉽고 빠르게 부팅할 수 있습니다.

다음 링크는 간단한 로깅을 훨씬 효율적으로 하기 위한 유용한 탄약을 제공합니다.

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

기존의 NSLogs를 변경하여 발신원 회선번호 및 클래스를 표시할 수 있습니다.프리픽스 파일에 코드 한 줄을 추가합니다.

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

예를 들어 간단합니다.

- (void) application Will Enter Forground : (UIApplication *) application {

    NSLog(@"%s", __PRETTY_FUNCTION__);

}

출력: [AppDelegate applicationWillEnterForground:]

위의 답변 위에 제가 표절해서 생각해낸 게 있어요.메모리 로깅도 추가.

#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

따라서 kLOGIF카테고리와 kLOGIFdetail의 현재 설정을 사용하여LTEQ와 같은 콜

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.

한 줄 한 줄씩 입력하는 데 필요한 몇 글자의 추가 문자를 찾을 수 있습니다.

  1. 코멘트 카테고리 전체의 온/오프 전환(예를 들어 모델이라고 표시된 콜만 보고)
  2. 더 높은 레벨의 번호 또는 더 낮은 번호로 표시된 가장 중요한 콜에 대한 세부 보고서

많은 사람들이 이게 좀 과잉 살상이라고 생각하겠지만, 누군가 그들의 목적에 적합하다고 생각할지도 모르니까..

언급URL : https://stackoverflow.com/questions/969130/how-to-print-out-the-method-name-and-line-number-and-conditionally-disable-nslog

반응형