2013-06-06 2 views
6

디버그 변수가 true 인 경우에만 NSLog을 실행하는 사용자 지정 NSLog() 메서드 DNSLog()을 만들려고합니다. 내가 참고로이 사용한사용자 지정 NSLog 메서드 (가변)

Undefined symbols for architecture i386: 
    "_DZNSLog", referenced from: 
     -[RestaurantInfoViewController viewDidLoad] in RestaurantInfoViewController.o 
ld: symbol(s) not found for architecture i386 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

: http://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

내가

-(void)DNSLog:(NSString *)formatString, ... 
{ 
    if(debug){ 
     va_list args; 
     va_start(args, formatString); 
     NSLog([[NSString alloc] initWithFormat:formatString arguments:args]); 
     va_end(args); 
    } 
} 

하지만

DNSLog(@"Hello %d",x); 

를 사용하여 호출하려고 내가 컴파일 오류가 나타납니다 잘못되어가는 ?

+5

나는 고급 재료에 빠지기 전에 C를 배워야한다고 생각합니다. C 함수의 구문과 Objective-C 메서드를 구별 할 수없는 것 같습니다 ... –

+1

또한 코드는 문자열 공격/오류의 형식에 취약합니다. 대신에'NSLogv (formatString, args);'를 사용해야한다. –

답변

14

의 방법입니다. Objective-C는 둘 다 있습니다. NSLog은 표준 함수이므로 NSLog(...)이라고 부릅니다. 메소드를 정의했습니다.

-(void)DNSLog:(NSString *)formatString, ... 

하지만 함수로 호출하려고했습니다. 당신의 메소드를 호출하려면 수행해야합니다 코드를 컴파일

[self DNSLog:@"Hello %d", x]; 

과 같이 글로벌 또는 인스턴스 debug 변수가 있어야합니다. 전역 인 경우 DNSLog을 함수로 정의 할 수 있습니다. debug이 메소드에 직접 액세스 할 수있는 유일한 인스턴스 변수 인 경우 작동하지 않습니다. 함수는 다음과 같이 시작됩니다.

void DNSLog(NSString *formatString, ...) 

함수의 본문은 메서드의 경우와 같습니다.

NSLog에는 컴파일러에게 형식 문자열을 인수로 사용한다는 것을 알려주기 위해 NS_FORMAT_FUNCTION이라는 특성이 있습니다. 컴파일러는 형식 문자열과 인수가 일치하는지 확인합니다.당신의 방법이나 기능을 쓰기 위해이 작업을 수행하려면

-(void)DNSLog:(NSString *)formatString, ... NS_FORMAT_FUNCTION(1,2); 

나 :

void DNSLog(NSString *formatString, ...) NS_FORMAT_FUNCTION(1,2); 

을 인터페이스 또는 헤더 파일에.

HTH.

+0

고마워 ... 네, 그 실수를 깨달았습니다. 지금 모든 작업이 가능합니다 :) – Kyuubi

+1

@Kyuubi - 네가 이것을 입력하는 동안 네가 생각한 것 중에 네가 NS_FORMAT_FUNCTION을 잊지 마라. 제비. – CRD

+0

알았습니다. 내 기능에 동일하게 추가. – Kyuubi

12

사용자 지정 메서드를 사용하는 대신이 매크로를 응용 프로그램 (.pch 파일)에 추가해보십시오.

#ifdef DEBUG 
#define MyLog(x, ...) NSLog(@"%s %d: " x, __FUNCTION__, __LINE__, ##__VA_ARGS__) 
#else 
#define MyLog(x, ...) 
#endif 

디버그 모드에있을 때 MyLog를 호출하는 사용자 지정 로그가 실행되며, 릴리스 될 때 아무 것도하지 않습니다. 또한 로그의 파일 및 행 번호와 같은 유용한 정보를 인쇄합니다.

+1

실제로 그의 질문은 "디버그 변수가 참일 때"로깅에 관한 것입니다. 그의 코드는 그가 제어하는 ​​별도의 디버그 변수가 있음을 나타냅니다. 또한, H2CO3는 단지 그것을 보는 방식으로 부르고 있습니다. 나는 같은 방식으로 느낀다. 나는 사람들이 코드를 복사하여 붙여 넣기를하고, 쓰여진 것과 똑같이 작동하지 않을 때 손실을 입을 것인지를 알기 때문에 대답에 대한 코드를 제공하지는 않는다. 나는 사람들이 그들이 작성한 코드를 이해해야한다고 생각한다. – borrrden

+0

그렇다면 그가 그것을 이해할 수 있도록 알려주는 답변을 게시하는 해결책이 아닙니까? 실제로 우리는 실제로 op가이 방법을 배우고 구현하는 데 도움이되는 게시물을 만듭니다. 그것에 덧붙이면, 뭔가를하기 위해 다른 방법을 공유하는 것이 잘못되면 안된다. 그러나 나는 지금 당신의 요점을 본다. – Eric

+0

감사합니다. 그것도 잘 작동합니다! 하지만 나중에 Log Function에 복잡한 부울 식과 중첩 된 if-else가있을 수 있으므로 MACRO 대신 새 함수를 모두 구현하려고했습니다. – Kyuubi

9

초보자에게 '귀중한', '격려'및 '지원'답변을 해주신 모든 분들께 감사드립니다.

나는 내 실수를 발견하고 여기에 수정 작업 코드 :

내가 사용하던 이전 방법은 내가 C를 사용하여 전화를하려고했던 오브젝티브 C 방법

-(void)DNSLog:(NSString *)formatString, ... 

을했다

void ZNSLog(NSString *format, ...){ 
    if(!ENABLE_DEBUGGING) 
     return; 
    va_list args; 
    va_start(args, format); 
    NSLogv(format, args); 
    va_end(args); 
} 

ZNSLog(@"Hello"); 

함수 호출.

관련 문제