2010-08-21 3 views
3

이상한 문제가 있습니다. 내 응용 프로그램에서 애플의 개인 프레임 워크에서 메서드를 사용하고 있습니다. 처음으로 전화를 걸면 작동합니다. 그 사이에 아무 것도없이 두 번째로 즉시 호출하면 충돌이 발생합니다. 그러나 두 통화 사이에 NSLog를 넣으면 멋지게 작동합니다. 그래서 NSLog를 제거하고 for-loops, sleep(), printf ("...") 및 fprintf (stderr, "...")를 NSLog를 에뮬레이트하기 위해 넣으려고했지만 도움이되지 않습니다. 어떻게 NSLog를 사용하는 방법을 알고 있는지 궁금합니다. 즉, NSLog는 실제로 메소드의 동작에 영향을 미치기 위해 무엇을합니까?NSLog는 실제로 무엇을합니까?

대단히 감사합니다!

편집 :

나는이 문제를 해결하기 위해 보인다. 나는 여기서 나의 해결책을 공유 할 것이고 그것이 어떤 사람들에게는 유용 할 수 있기를 희망한다.

MultitouchSupport.framework를 사용하여 멀티 터치 관련 응용 프로그램을 만들고 있습니다. http://aladino.dmi.unict.it/?a=multitouch의 코드를 복사하고 루프 끝에 CFRelease을 추가했습니다. 그래서, 기본적으로 내 주요 방법은 다음과 같습니다

int main(void) { 
    int i; 
    NSMutableArray* deviceList = (NSMutableArray*)MTDeviceCreateList(); //grab our device list 
    for(i = 0; i<[deviceList count]; i++) { //iterate available devices 
     MTRegisterContactFrameCallback([deviceList objectAtIndex:i], touchCallback); //assign callback for device 
     MTDeviceStart([deviceList objectAtIndex:i], 0); //start sending events 
    } 
    CFRelease((CFMutableArrayRef)deviceList); 
    printf("Ctrl-C to abort\n"); 
    sleep(-1); 
    return 0; 
} 

잠시 동안 실행 한 후, 그것은 "프로그램 신호 수신 :"가 표시됩니다 "."EXC_BAD_ACCESS를 내가 MTDeviceStart 아래 NSLog를 넣어 경우

그러나
#0 0x7fff8795496e in ParsedMultitouchFrameRepInitialize 
#1 0x7fff879565b1 in mt_HandleMultitouchFrame 
#2 0x7fff87955a03 in mt_DequeueDataFromDriver 
#3 0x7fff87955b29 in mt_DequeueMultitouchDataFromDriverThreadEntry 
#4 0x7fff831b3456 in _pthread_start 
#5 0x7fff831b3309 in thread_start 

, 그것은 충돌하지 않습니다 그리고 여기에는 스택 추적입니다.

원래 코드에 CFRelease((CFMutableArrayRef)deviceList)을 추가 한 이유는 * Create * 또는 * Copy *라는 이름의 함수로 만든 객체가 스스로 출시되어야한다고 생각하기 때문입니다. 그러나 원래 코드처럼 제거하면 NSLog를 사용하지 않아도 크래시가 발생하지 않습니다.

그래서 내가 deviceList을 너무 일찍 릴리스했기 때문일 수 있습니다. 그렇다면 NSLog가 충돌을 막을 수있는 이유는 무엇입니까?

+5

아마 NSLog와 관련이 없습니다. 나는 약간의 코드를 게시 할 것이다. –

+0

질문에 코드와 스택 추적을 모두 편집하십시오. –

+0

네이밍 규칙은 정확하지만 'MTDeviceCreateList'는 개인 기능이기 때문에 위반하거나 위반하고있을 수 있습니다. (아마 "프로세스 기간 동안 살아 남기 위해 의도 된 장치 배열을 만들고 포인터를 그 장치로 되돌려 놓는 것을 의미합니다.") Instruments 's Zombies 장비에서 프로그램을 실행하십시오 (충돌시). 이를 통해 공개가 과다 출시인지 여부를 입증하거나 충돌의 진정한 원인을 판단 할 수 있어야합니다. –

답변

0

메모리 관리에 문제가 될 수 있습니다. 아마도 외부의 릴리스 일 수 있습니다. 추적을 게시하면 문제를 추적하는 데 도움이 될 수 있습니다. (밝혀진 바와 같이, 내가 따라간 트위터의 누군가는 지난 밤에 이와 비슷한 것을 언급했다.)

+0

와우! 고맙습니다. 내 코드에서 CFRelease를 제거하려고 시도했지만 이제는 완벽하게 작동합니다. 왜 그래도 모르겠다. 방금 내 질문에 내 코드를 추가했습니다. – ifvc

+0

조심하십시오 : 너무 일찍 석방되었지만 어쨌든 석방되어야하는 경우, 이제는 충돌이 발생하지 않고 대신 새어 나옴을 의미합니다 (즉, 타이밍 문제 였고 처음) –

1

시간이 오래 걸립니다. 이유가 확실하지 않습니다. 날짜/시간, 프로세스 이름, 프로세스 ID, 스레드 ID 및 요청한 문자열을 인쇄합니다. I 도 syslogd에 로그 메시지를 보냅니다 (Xcode 또는 iPCU의 콘솔에 여러 줄의 NSLog가 하나의 항목으로 표시됨). IPC가 중요 할 수도 있습니다.

시도가 작동하지만 더 출력을 얻을 수없는 경우,() man 3 syslog를 참조 우선 순위를 변경하려고 시스템 로그() (#import <syslog.h> 다음 syslog(LOG_INFO, "Hello there!");을 사용하여이 유사

+0

예, NSLog는 syslog와 마찬가지로 ASL에 메시지를 보냅니다. 나는 당신이 syslog가 다르게 할 것을 기대하고 있는지 확신하지 못한다. 그냥 stderr로 출력하지 않겠는가? –

+0

"NSLog를 두 번 호출 사이에 넣으면 작동합니다"라고 말하면서 syslog()가 NSLog가 "작동하게"하는 일을 할 수 있다고 제안했습니다. –

2

뭔가 :.

static inline void NSLogMessageString(NSString *string){ 
    NSString *date=[[NSDate date] 
    descriptionWithCalendarFormat:@"%Y-%m-%d %H:%M:%S.%F" 
         timeZone:nil locale:nil]; 
    NSString *process=[[NSProcessInfo processInfo] processName]; 

    NSLogFormat(@"%@ %@[%d:%lx] %@",date,process,NSPlatformProcessID(),NSPlatformThreadID(),string); 
} 

void NSLogv(NSString *format,va_list arguments) { 
    NSString *string=NSStringNewWithFormat(format,nil,arguments,NULL); 

    NSLogMessageString(string); 

[string release]; 
} 

void NSLog(NSString *format,...) { 
    va_list arguments; 

    va_start(arguments,format); 

    NSLogv(format,arguments); 
} 

감사합니다 이 질문을 듣기 위해 필자는 디버깅 변수를 추가 할 수 있도록 다시 작성하려고 했으므로 필요한 경우 모든 NSLogging 호출을 끌 수 있습니다.

+0

- NSObjcRuntime에 있습니다. –

1

NSLog는 실행중인 것과 같은 문제에 영향을 미칠 수 있습니다. o 백그라운드 스레드에서 NSLog를 호출 할 때 stdout에 독점적으로 액세스해야하기 때문에 스레드가 실행되는 순서에 영향을 미치기 때문입니다.printf는 스레드에 대한 까다로운 문제를 디버깅 할 때 종종 이런 이유로 "heisenbugs"를 발생시킵니다 (예 : 검사 할 때 동작을 변경 함).

관련 문제