누군가 iPhone 앱 에서이 스택 트레이스에 대해 나에게 손을 줄 수 있습니까?
-
12-09-2019 - |
문제
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x30011940 in objc_msgSend ()
#1 0x30235f24 in CFRelease ()
#2 0x308f497c in -[UIImage dealloc] ()
#3 0x30236b78 in -[NSObject release] ()
#4 0x30a002a0 in FlushNamedImage ()
#5 0x30250a26 in CFDictionaryApplyFunction ()
#6 0x30a001a4 in _UISharedImageFlushAll ()
#7 0x30a00738 in +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] ()
#8 0x3054dc80 in _nsnote_callback ()
#9 0x3024ea58 in _CFXNotificationPostNotification ()
#10 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#11 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:] ()
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
#13 0x30a006a8 in -[UIApplication _receivedMemoryNotification] ()
#14 0x30a005d8 in _memoryStatusChanged ()
#15 0x30217416 in __CFNotificationCenterDarwinCallBack ()
#16 0x3020d0b0 in __CFMachPortPerform ()
#17 0x30254a76 in CFRunLoopRunSpecific ()
#18 0x3025416a in CFRunLoopRunInMode ()
#19 0x320452a4 in GSEventRunModal ()
#20 0x308f037c in -[UIApplication _run] ()
#21 0x308eea94 in UIApplicationMain ()
#22 0x00002096 in main (argc=1, argv=0x2ffff514)
현재 프로그램에 매우 이상한 오류가 있습니다. 때때로 그것은 발생하지만 때로는 그렇지 않습니다. 그러나 다음은 무슨 일이 일어나고 있는지에 대한 요약입니다.
프로그램이 시작될 때 :
- 저장된 데이터 (짧은 단지 13 개의 요소로 구성됨)가 존재하는 경우로드됩니다.
- 1014 줄을 포함하는 거대한 plist가 nsmutabledictionary에로드됩니다.
- 78 줄을 포함하는 또 다른 plist가 nsarray에로드됩니다.
- .mp4 영화가 재생됩니다.
오류는 OpenGl es 뷰가 제거되고 사용자는 nsmutabledictionary에서 1014 문자열의 문자열 중 하나를 보려고합니다.
이 오류는 시뮬레이터에서 발생하지 않습니다. 그것은 iPhone에서만 발생하며 때로는 잘 실행되지만 때로는 분쇄됩니다.
그러나 StackTrace를 읽은 후에는 cfdictionaryApplyFunction이 표시되므로 가능한 원인 중 하나 일 수 있다고 생각했습니다. 시뮬레이터에서는 너무 빨리 읽을 수 없기 때문에 Plist의 전체 사전이 순간적으로로드되어 장치에서는 더 느리게 읽히기 때문입니까? 솔직히, 나는 사전이 어떻게 작동하는지 정확히 모른다. 순간적으로 모든 1014 줄을 읽거나 다른 스레드를 사용하여 천천히 읽습니까? 조언을 해주세요. 고맙습니다.
해결책
당신이 얻을 때 EXC_BAD_ACCESS
, 그것은 종종 당신이 존재하지 않는 객체의 메소드를 호출하려고한다는 것을 의미합니다. 아마도 거래 되었기 때문일 것입니다.
흔적의 중간 쯤에 일부가 있습니다 메모리 경고 다음과 같은 통화
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
코드 중 어느 것도 곧장 메모리가 낮을 때 충돌이 발생하지만 시스템 알림을 유발합니다.
프레임 #0에 가까워지면 UIImage
객체, 이것은 나쁜 접근성 인 것 같습니다.
이를 바탕으로 한 가지 추측은 편의 생성자의 자동 저명한 반환 값에 대한 포인터를 할당하고 있다는 것입니다. 그런 다음 객체가 자동으로 표시되며 이미지를 직접 사용하지 않기 때문에 괜찮다고 생각할 수 있지만 메모리 경고는 액세스하려고합니다. 예를 들어:
@interface MyClass {
UIImage* myImage;
}
// ...
- (id) init { /* the usual stuff */
myImage = [UIImage imageNamed:@"bob_the.png"];
return self;
}
이 예에서는 재산이 설정되어 있어도 myImage
, 당신은 실제로 값을 통해 이미지를 유지하지 않습니다. self.myImage
. 따라서이 호출 직후 이미지가 출시되고 No Man 's Land에 대한 포인터가 있습니다.
코드를 보지 않고는 그것이 실제로 진행되는지 알 수있는 방법이 없지만, 만드는 것은 쉬운 실수의 한 가지 유형입니다.
이러한 관련 질문은 유사한 충돌에 대한 팁을 제공합니다. EXC_BAD_ACCESS
디버깅 질문 1 그리고 질문 2.
마지막으로, 그 중 어느 것도 도움이되지 않으면 최소 재생산 당신의 문제의. 이 작업을 수행하는 어려운 방법은 코드를 복사하고, 절반을 삭감하고, 오류가 여전히 있는지 확인하고, 오류를 재현 할 수있는 가장 작은 코드를 얻을 때까지 반복하는 것입니다. 쉬운 방법을 알고 있다면 저에게 알려 주시면 일반적으로 거기에서 디버깅하기가 훨씬 쉽습니다 (그리고 StackoverFlow 질문으로 더 많이 게시 할 수 있습니다!).
다른 팁
당신은 설정하고 싶을 수도 있습니다 NSZombiesEnabled
환경 변수. 이렇게하면 앱이 충돌하지 않습니다 EXC_BAD_ACCESS
릴리스 된 객체에 액세스 할 때는 유익한 메시지를 콘솔에 로그인합니다. 이 블로그 게시물 Xcode에서 어떤 일이 일어나고 설정하는 방법을 잘 설명합니다. 어쨌든, 생산 릴리스 에서이 옵션을 비활성화하는 것을 잊지 마십시오. 그렇지 않으면 객체가 출시되지 않기 때문입니다!