EXC_BAD_ACCESS 신호 수신


290

응용 프로그램을 장치에 배포하면 몇 번의주기 후에 프로그램이 다음 오류와 함께 종료됩니다.

Program received signal: "EXC_BAD_ACCESS".

이 프로그램은 iPhone 시뮬레이터에서 아무런 문제없이 실행되며 한 번에 하나씩 지침을 단계별로 실행하는 한 디버그 및 실행됩니다. 다시 실행하자마자 EXC_BAD_ACCESS신호를칩니다.

이 특별한 경우에는 가속도계 코드에서 오류가 발생했습니다. 시뮬레이터 내에서 실행되지 않으므로 오류가 발생하지 않습니다. 그러나 일단 장치에 배포되면 실행됩니다.

이 질문에 대한 대부분의 답변은 일반적인 EXC_BAD_ACCESS오류를 다루 므로 무시 무시한 Bad Access 오류에 대한 포괄적 인 정보로 열어 두겠습니다.

EXC_BAD_ACCESS일반적으로 잘못된 메모리 액세스의 결과로 발생합니다. 자세한 내용은 아래 답변을 참조하십시오.

EXC_BAD_ACCESS이전에 그 신호 를 만났 습니까? 어떻게 처리 했습니까?

답변:


196

귀하의 설명에서 가장 가능성이 높은 설명은 메모리 관리에 약간의 오류가 있다고 생각합니다. 당신은 몇 주 동안 iPhone 개발 작업을 해왔지만 일반적으로 Objective C에 경험이 있는지 여부는 아닙니다. 다른 배경을 가지고 있다면 메모리 관리 규칙을 실제로 내부화하기 전에 약간의 시간이 걸릴 수 있습니다.

할당 함수 (일반적으로 정적 할당 방법이지만 몇 가지 다른 것) 또는 복사 방법에서 얻은 것은 메모리도 소유하고 있으며 완료되면 해제해야합니다.

그러나 팩토리 메소드 (예 :)를 포함하여 다른 것에서 무언가를 얻는다면 자동 [NSString stringWithFormat]릴리스 참조를 갖게 될 것입니다. 즉, 다른 코드로 나중에 언젠가 릴리스 될 수 있다는 것을 의미합니다. 즉시 유지하는 기능 이상으로 유지하십시오. 그렇지 않으면 에뮬레이터 테스트 중에 메모리를 사용하는 동안 메모리가 할당 된 상태로 유지되거나 해제되었지만 우연히 여전히 유효하지만 장치에서 실행될 때 해제되어 잘못된 액세스 오류로 표시 될 수 있습니다.

이러한 것들을 추적하는 가장 좋은 방법은 어쨌든 명백한 문제가 없더라도 좋은 아이디어는 인스트루먼트 도구에서, 특히 누출 옵션을 사용하여 앱을 실행하는 것입니다.


2
내 앱에 중요하지 않은 가속도계 샘플링 코드가있어 제거 후 나쁜 액세스 오류를 제거했습니다. 시뮬레이터에 가속도계가 없다는 것을 고려하면 의미가 있습니다. 이 오류가 발생하기 전에 일주일 동안이 코드가 수정되지 않고 존재했다는 것이 이상합니다.
Héctor Ramos

나는 Objective-C를 처음 사용하므로 대부분의 문제는 메모리 관리에서 발생합니다. C ++에서 몇 년 후, 지난 3-4 년 동안 대부분 Java를 사용해 왔기 때문에 메모리 관리에 대해 녹슬 었습니다. 답변 주셔서 감사합니다!
Héctor Ramos

4
문제 없습니다. 문제를 해결 했다니 다행입니다. 메모리 관리는 실제로 어려운 일이 아닙니다. 규칙을 배우고 좋은 습관을들이십시오.
philsquared 08.

내가 겪었던 문제는 내가 만든 문자열 (및 이와 같은)을 릴리스하는 데 너무 적극적 인 것 같습니다. 나는 언제 무엇을 발표해야하는지 100 % 확신하지 못하지만 Phil의 대답은 확실히 도움이되었습니다.
pluckyglen

내가 제대로 따라 갔다면 cmculloh, 그렇습니다. objectAtIndex에서 리턴 된 오브젝트를 소유하지 않습니다.
philsquared

101

EXC_BAD_ACCESS의 주요 원인은 해제 된 개체에 액세스하려고하기 때문입니다.

이 문제를 해결하는 방법을 알아 보려면 다음 문서를 읽으십시오. DebuggingAutoReleasePool

"자동 해제 된 객체 해제"를 생각하지 않더라도 적용됩니다.

이 방법은 매우 효과적입니다. 나는 항상 큰 성공으로 그것을 사용합니다 !!

요약하면, 이것은 Cocoa의 NSZombie 디버깅 클래스와 명령 줄 "malloc_history"도구를 사용하여 코드에서 어떤 릴리스 된 객체에 액세스했는지 정확하게 설명합니다.

각주 :

계측기를 실행하고 누출을 검사해도 EXC_BAD_ACCESS 문제를 해결하는 데 도움이되지 않습니다. 메모리 누수가 EXC_BAD_ACCESS와 아무 관련이 없다고 확신합니다. 누수의 정의는 더 이상 액세스 할 수없는 개체이므로 호출 할 수 없습니다.

업데이트 : 이제 계측기를 사용하여 누출을 디버깅합니다. Xcode 4.2에서 Product-> Profile을 선택하고 Instruments가 시작되면 "Zombies"를 선택하십시오.


18
이 주석은 매우 중요합니다. 누출로 인해 EXC_BAD_ACCESS가 발생할 수 없습니다 (다른 문제가 있음). EXC_BAD_ACCESS loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
Lou Franco

4
Xcode의 좀비 도구는 훌륭합니다! 몇 시간이 아니라 3 분 안에 범인을 찾았습니다.
Aram Kocharyan

1
위의 링크에서 답변을 사용할 수 없습니다. 404 찾을 수 없음 오류를 표시합니다.
Tejas

12

EXC_BAD_ACCESS 신호는 시스템 호출에 유효하지 않은 포인터를 전달한 결과입니다. OS X에서 테스트 프로그램으로 오늘 일찍 하나를 얻었습니다. 초기화되지 않은 변수를 전달했습니다.pthread_join() .

iPhone 개발에 익숙하지는 않지만 시스템 호출에 전달하는 모든 버퍼 포인터를 다시 확인해야합니다. 컴파일러의 경고 수준을 완전히 높이십시오 (gcc로 -Wall-Wextra옵션 사용). 시뮬레이터 / 디버거에서 가능한 한 많은 진단을 활성화하십시오.


8

내 경험상 이것은 일반적으로 잘못된 메모리 액세스로 인해 발생합니다. 모든 포인터, 특히 객체 포인터가 초기화되어 있는지 확인하십시오. MainWindow.xib 파일을 사용하는 경우 필요한 모든 연결로 올바르게 설정되어 있는지 확인하십시오.

종이 검사 중 아무것도 켜지지 않고 단일 스테핑시 발생하지 않는 경우 NSLog () 문으로 오류를 찾으십시오. 오류. 그런 다음 해당 줄에 중단 점을 설정하고 프로그램을 실행하십시오. 중단 점에 도달하면 모든 변수와 그 안에있는 객체를 검사하여 예상치 않은 것이 있는지 확인하십시오. 특히 객체 클래스가 예상치 못한 변수를 주시하십시오. 변수에 UIWindow가 포함되어 있지만 NSNotification이있는 경우 디버거가 작동하지 않을 때 동일한 기본 코드 오류가 다른 방식으로 나타날 수 있습니다.


7

방금 EXC_BAD_ACCESS를 추적하는 데 몇 시간을 보냈으며 NSZombies 및 기타 환경 변수가 아무 것도 말하지 않는 것으로 나타났습니다.

나에게는 형식 지정자가 있지만 바보가 전달되지 않은 바보 같은 NSLog 문이었습니다.

NSLog(@"Some silly log message %@-%@");

에 의해 고정

NSLog(@"Some silly log message %@-%@", someObj1, someObj2);

6

2010 WWDC 비디오는 Apple 개발자 프로그램의 모든 참가자가 사용할 수 있습니다. "세션 311-인스트루먼트를 사용한 고급 메모리 분석"은 인스트루먼트에서 좀비를 사용하고 다른 메모리 문제를 디버깅하는 예제를 보여줍니다.

로그인 페이지에 대한 링크를 보려면 여기를 클릭하십시오 .


6

완전한 대답은 아니지만이를받은 특정 상황은 자동 릴리스를 사용하려고 시도하여 '죽은'객체에 액세스하려고 할 때입니다.

netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];

예를 들어, 실제로 이것을 '알림'하기 위해 객체로 전달하고 (원하는대로 관객, 관찰자 ​​등으로 등록) 알림이 전송되면 이미 사망했으며 EXC_BAD_ACCESS를 얻습니다. [[MyNetObject alloc] init]적절하게 변경하고 나중에 해제하면 오류가 해결되었습니다.

이 문제가 발생할 수있는 또 다른 이유는 예를 들어 객체를 전달하여 저장하려고하는 경우입니다.

myObjectDefinedInHeader = aParameterObjectPassedIn;

나중에 myObjectDefinedInHeader에 액세스하려고하면 문제가 발생할 수 있습니다. 사용 :

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

필요한 것일 수도 있습니다. 물론 이것들은 내가 겪은 것에 대한 몇 가지 예일 뿐이며 다른 이유가 있지만, 이것들은 애매하게 보일 수 있으므로 언급 할 수 있습니다. 행운을 빕니다!


5

이 상황이 발생할 수있는 다른 상황을 추가하기 만하면됩니다.

나는 코드를 가지고 있었다 :

NSMutableString *string;
[string   appendWithFormat:@"foo"];

분명히 나는 ​​문자열에 메모리를 할당하는 것을 잊었다.

NSMutableString *string = [[NSMutableString alloc] init];
[string   appendWithFormat:@"foo"];

문제를 해결합니다.


문자열이 nil로 초기화되고 nil에서 메소드를 호출하는 null 객체 패턴을 사용하면 아무것도 수행되지 않으므로 오류가 발생하지 않습니다.
Liron Yahdav

5

EXC_BAD_ACCESS 예외가 발생하기 전에 포착하는 또 다른 방법은 정적 분석기입니다. 은 XCode 4+ 입니다.

제품> 분석 (shift + cmd + B)으로 정적 분석기를 실행하십시오. 분석기에서 생성 된 메시지를 클릭하면 문제가되는 개체의 유지 / 해제 시퀀스를 보여주는 소스에 다이어그램이 오버레이됩니다.

여기에 이미지 설명을 입력하십시오


5

objc_exception_throw에 중단 점을 설정하는 것이 유용하다는 것을 알았습니다. 그렇게하면 EXC_BAD_ACCESS를 얻을 때 디버거가 중단됩니다.

지침은 여기에서 찾을 수 있습니다 DebuggingTechniques


4

"할당하지 않았거나 유지하지 않은 경우 해제하지 마십시오"라는 간단한 규칙을 사용하십시오.


1
"... copy it ..."으로 해당 규칙을 확장하면 괜찮을 것입니다.
까지

4

EXC_BAD_ACCESS를 디버깅하는 방법

위의 링크를 확인하고 표시된대로하십시오 .... NSZombies 사용에 대한 간단한 지침

응용 프로그램을 실행하고 실패한 후 ( "EXC_BAD_ACCESS"대신 "중단됨"으로 표시해야 함 ... 콘솔 확인 (실행> 콘솔) ... 액세스하려는 개체를 알려주는 메시지가 표시됩니다.


3

지난 4 시간 동안이 오류를 해결하기 위해 코드를 디버깅하고 리팩토링했습니다. 위의 게시물로 문제가 발생했습니다.

이전 속성 : startPoint = [[DataPoint alloc] init]; startPoint = [DataPointList objectAtIndex : 0];
. . . x = startPoint.x-10; // EXC_BAD_ACCESS

이후 속성 : startPoint = [[DataPoint alloc] init]; startPoint = [[DataPointList objectAtIndex : 0] 유지];

안녕 EXC_BAD_ACCESS


나는 비슷한 실수를했다. 충돌을 일으킨 인스턴스를 유지하는 것을 잊어 버렸습니다. 당신의 경험은 저를 찾아 내었습니다. 감사!
David.Chu.ca

3

완료되면 '문자열'을 공개하기를 바랍니다.


3

init-Method에서 자기 자신을 반환하는 것을 잊었습니다 ...;)


이것은 런타임 동안 EXC_BAD_ACCESS가 아니라 컴파일 시간 경고 / 오류 여야합니다.
stigi

3

이것은 훌륭한 실입니다. 내 경험은 다음과 같습니다. 속성 선언에서 retain / assign 키워드를 엉망으로 만들었습니다. 나는 말했다:

@property (nonatomic, assign) IBOutlet UISegmentedControl *choicesControl;
@property (nonatomic, assign) IBOutlet UISwitch *africaSwitch;
@property (nonatomic, assign) IBOutlet UISwitch *asiaSwitch;

내가 말했던 곳

@property (nonatomic, retain) IBOutlet UISegmentedControl *choicesControl;
@property (nonatomic, retain) IBOutlet UISwitch *africaSwitch;
@property (nonatomic, retain) IBOutlet UISwitch *asiaSwitch;

1
이상해 왜 IBOutlet을 유지해야합니까? 그들의 관리는 자동적으로 이루어집니다.
jv42

3

큰 배열을 포함하는 C 메서드를 실행하는 동안에 만 iPhone에서 EXC_BAD_ACCESS가 발생했습니다. 시뮬레이터는 코드를 실행하기에 충분한 메모리를 줄 수 있었지만 장치는 사용할 수 없었습니다 (배열은 백만 자이므로 약간 과도했습니다!).

EXC_BAD_ACCESS는 메소드의 진입 점 직후에 발생했으며 배열 선언 근처에 없기 때문에 꽤 혼란 스럽습니다.

어쩌면 다른 사람이 내 두 시간의 머리카락을 깎아서 혜택을 볼 수도 있습니다.


3

에서 할당되지 않은 포인터를 꺼내는 것을 잊었습니다. dealloc . UINavigationController의 rootView에서 exc_bad_access를 얻었지만 가끔 만 가능합니다. viewDidAppear {}을 통해 반쯤 충돌했기 때문에 문제가 rootView에 있다고 가정했습니다. 잘못된 dealloc {} 릴리스로 뷰를 표시 한 후에 만 ​​발생하는 것으로 나타났습니다.

"EXC_BAD_ACCESS"[330으로 전환 중] 지금 프로그램에 사용할 수있는 메모리가 없습니다 : malloc을 호출하는 것이 안전하지 않습니다

나는 할당을 시도하는 것이 문제라고 생각했다. 내가 비 할당을 해제하려고하는 곳이 아닌 D' oh!


3

EXC_BAD_ACCESS를 처리하는 방법

때로는 EXC_BAD_ACCESS 오류가 발생하면 xcode가 main.m 클래스의 오류를 표시하여 충돌이 발생하는 위치 (때로는)에 대한 추가 정보를 제공하지 않는다고 생각합니다.

그 당시 Xcode에서 예외 중단 점을 설정하여 예외가 발생했을 때 중단 점이 배치되고 해당 행에서 충돌이 발생한 사용자에게 직접 친밀감을 줄 수 있습니다.

여기에 이미지 설명을 입력하십시오


2

메소드 매개 변수의 유효성을 검사하기위한 NSAssert () 호출은 추적 및 nil 전달을 피하는 데 매우 유용합니다.


2

방금이 문제가있었습니다. 나에게 이유는 CoreData 관리 객체를 삭제하고 나중에 다른 곳에서 읽으려고했습니다.


2

지난 4 시간 동안이 오류를 해결하기 위해 코드를 디버깅하고 리팩토링했습니다. 위의 게시물로 문제가 발생했습니다.

전에 속성 :

startPoint = [[DataPoint alloc] init] ;
startPoint= [DataPointList objectAtIndex: 0];
x = startPoint.x - 10; // EXC_BAD_ACCESS

후 속성 :

startPoint = [[DataPoint alloc] init] ;
startPoint = [[DataPointList objectAtIndex: 0] retain];

안녕 EXC_BAD_ACCESS

답변 주셔서 감사합니다. 하루 종일이 문제로 어려움을 겪고 있습니다. 당신은 굉장합니다!


4
startPoint를 즉시 덮어 쓰지 않습니까? 나는 당신이 그 첫 줄을 전혀 필요로하지 않는다고 생각합니다.
toxaq

2
변수를 즉시 다른 변수로 덮어 쓰려면 변수를 할당하고 초기화 할 필요가 없습니다. 첫 번째 과제에서 객체를 유출하고 있습니다.
dreamlax

2

그냥 추가

Lynda.com 에는 환상적인 DVD라는

iPhone SDK 필수 교육

6 장, 레슨 3은 EXEC_BAD_ACCESS 및 좀비 작업 에 관한 입니다.

오류 코드뿐만 아니라 좀비를 사용하여 릴리스 된 객체에 대한 자세한 정보를 얻는 방법을 이해하는 것이 좋았습니다.


2

오류가 무엇인지 확인하려면

NSZombieEnabled를 사용하십시오.

애플리케이션에서 NSZombieEnabled 기능을 활성화하려면 다음을 수행하십시오.

프로젝트> 활성 실행 파일 편집을 선택하여 실행 가능 정보 창을여십시오. 인수를 클릭하십시오. “환경에서 설정할 변수”섹션에서 추가 (+) 버튼을 클릭하십시오. 이름 열에 NSZombieEnabled를 입력하고 값 열에 YES를 입력하십시오. NSZombieEnabled 항목의 확인 표시가 선택되어 있는지 확인하십시오.

iPhoneSDK 에서이 답변을 찾았습니다.


2

나는 이것이 얼마 전에 요청되었다는 것을 알고 있지만이 스레드를 읽은 후 XCode 4.2의 솔루션을 찾았습니다. 제품-> 구성표 편집-> 진단 탭-> 좀비 개체 사용

할당 해제 된 객체로 전송되는 메시지를 찾도록 도와줍니다.


2

무한 재귀가있을 때이 오류가 발생할 수 있다고 생각합니다. 이것은 나를위한 경우였습니다.


1

또 다른 가능성 : 대기열의 블록을 사용하면 현재 할당이 해제 된 다른 대기열의 객체에 쉽게 액세스 할 수 있습니다. 일반적으로 GUI에 무언가를 보내려고 할 때. 예외 중단 점이 이상한 곳에 설정되어 있으면 이것이 원인 일 수 있습니다.


1

내가 사용하지 않았기 때문에 그것을 가지고 [self performSegueWithIdentifier:sender:]-(void) prepareForSegue:(UIstoryboardSegue *)권리


1

잊어 안 @치료, 문자열을 만들 때 기호 C-stringsNSStrings뜻 원인EXC_BAD_ACCESS .

이것을 사용하십시오 :

@"Some String"

이보다는 :

"Some String"

PS-일반적으로 array레코드가 많은 컨텐츠를 채울 때 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.