2010-01-29 5 views
0

디버깅 방법을 알 수없는 버그에 찔린 것 같습니다. 기본적으로 시뮬레이터에서 코드를 실행하면 모든 것이 잘됩니다.Debuggin iPhone 앱에 전화

그러나 실제 장치로 갈 때 EXC_BAD_ACCESS 오류가 발생합니다. 불행히도, 디버거에서 전화를 실행할 때 저주받은 것은 정상적으로 작동하므로 오류가 발생하는 곳을 판단 할 방법이 없습니다.

나는 재현 할 수없는 하나의 스택 추적을 얻었으므로 문제를 일으키는 코드가이 코드 라인에 있다고 확신한다. 그것은) 할 수있는 방법 :

[[NSNotificationCenter defaultCenter] postNotificationName:@"SubscriberChanged" object: nil]; 

실제 오류에 대한 4 개의 프레임이 라인 아래 objc_msgSend에 있었다, 그러나 그것의 아이폰 SDK의 일부가 될 것으로 보인다 코드에서, 그래서 원본이없는 그것을 검사하십시오.

아무도 내가이 문제가 어디 있는지 알아낼 수있는 방법에 대한 몇 가지 지침을 줄 수 있습니까? 나는이 일을 발송할 마감 기한이 있으며, 나는 이것을 이렇게 내버려 둘 수 없다 ...

마침내 이것을 디버거에서 재현 할 수 있었다. 내가 얻은 스택 추적은 다음과 같습니다.


#0 0x30011940 in objc_msgSend() 
#1 0x3054dc80 in _nsnote_callback() 
#2 0x3024ea58 in _CFXNotificationPostNotification() 
#3 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:]() 
#4 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:]() 
#5 0x000027c6 in -[My2CentsAppDelegate handleMOCChange:] (self=0x1159d0, _cmd=0x2bf90, notification=0x147400) at /Users/sdussin/Desktop/UPOD Research LLC/Development/My2Cents/Classes/My2CentsAppDelegate.m:52 
#6 0x3054dc80 in _nsnote_callback() 
#7 0x3024ea58 in _CFXNotificationPostNotification() 
#8 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:]() 

스택 추적의 프레임 5는 위의 행에 해당합니다. 디버거에서 충돌을 반복 할 수없는 경우

답변

2

, 당신은 그것을 해결하기 위해 다른 방법을 시도 할 수 있습니다 :

  • 검토 코드를 (아마도 코드 검토를 위해 친구 나 동료에게)
  • 추가 logging와 주장
  • 에서 [] 그 소리 2 정적 분석기를 사용할 수 있는지 확인하고 경고를 순종하는 모든 (또는 적어도 대부분의) 컴파일러 경고를 활성화하고 순종

특히 clang은 메모리 관리 버그를 찾는 데 상당히 도움이됩니다. EXC_BAD_ACCESS는 하나의 냄새를 풍깁니다.

아마 NSNotificationCenter으로 등록한 옵서버 중 한 명이 석방되었습니다. ,

중요을 기억하거나 removeObserver : 이름 : 알림 센터 은 당신 등록 취소 관찰자 ( removeObserver 사용하는지 확인해야합니다 따라서, 을 옵저버를 유지하지 않는 전에 객체를 :) 그들은 할당이 해제됩니다. (그렇지 않으면 중심이 해제 된 객체에 메시지를 보내는 경우, 당신은 런타임 오류가 발생합니다.)

+0

알림이 문제가되었음을 나타냅니다. 분명히 내 뾰족하게 붙은 모양의 뷰 객체의 인스턴스가 여러 개있었습니다. 로드가 완료되면 각각 알림에 등록되고 그 중 하나만 유지됩니다. 나머지는 공개되었지만 통지를 위해 등록 취소하지 못했습니다. 모두 감사합니다 ... – Steve

-1

을 일반적으로, 당신이 뭔가 장치를 시뮬레이터에서 실행이 아닌 경우를 얻을 때 또는 그 반대의 경우, 원인은 충돌하는 프로세서에 대해 컴파일되지 않은 라이브러리/프레임 워크입니다.

경우에 따라 장치에서 제대로 작동하지만 i386에서 실행되는 시뮬레이터에서 충돌하는 ARM 라이브러리/프레임 워크가있을 수 있습니다.그 통지에 등록 된 객체의 상속을 확인합니다.

2

NSZombieEnabled (Google it)를 사용하면이 종류의 것을 추적 할 수 있습니다. 그 외에, 나는 두 번째 oefe : 당신은 아마도 일부 관측자를 등록 해제해야한다. 언로드되었지만 여전히 관찰자로 등록 된 뷰 컨트롤러.

+0

아주 좋은 충고는 - 넣어 있는지 확인 (의 GetEnv ("NSZombieEnabled") ||의 GetEnv ("NSAutoreleaseFreedObjectCheckEnabled"))의 경우 \t \t NSLog ("NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled가 활성화!"@); 을 입력해야합니다. 필요하지 않을 때 꺼야한다는 경고 메시지가 표시됩니다. –

+0

서식 지정에 대해 죄송합니다. 댓글 상자에는 코드 태그가 없습니다. –

+0

내가 가지고있는 질문 중 하나는 전화로 실행 중이고 디버거를 사용하지 않는 경우 어떻게 NSZombieEnabled의 출력을 볼 수 있습니까? 나는 디버거에서 실행될 때 콘솔에 좀비가 로깅되었다는 인상을 받고 있었지만 전화로 어디로 갔습니까? – Steve

1

전송중인 알림에 대해 일부 개체가 등록되었으며 해제되기 전에 가입을 취소하지 않았기 때문에 충돌이 발생했습니다. 따라서 알림을 보내면 해당 개체를 다시 호출하여 호화를 시도합니다.

구독중인 코드의 모든 위치를 살펴보고 수신 거부를 놓친 위치를 확인하십시오 (예 : dealloc에서 가입을 취소 했습니까?).

NSZombieEnabled = YES는 XCode 프로젝트 브라우저에서 실행 파일을 마우스 오른쪽 버튼으로 클릭하고 Arguments 탭으로 이동하여 환경 변수에 추가함으로써 설정 한 환경 플래그입니다. 그런 다음 로그를보고, 통지를 보내면 "할당 해제 된 인스턴스로 메시지가 전송되었습니다"와 같은 메시지가 표시됩니다.

1

"압정 추적 (tack trace)은"SubscriberChanged "알림에 대해 등록 된 개체 할당이 취소되었음을 알려줍니다. 이 문제를 처리하는 가장 쉬운 방법은 "SubscriberChanged"알림에 등록하고 [dealloc] 메서드에서 등록을 취소하는 모든 클래스를 찾는 것입니다.