ViewController respondsToSelector : 할당 해제 된 인스턴스로 메시지 전송 (CRASH)


95

좋아, 여기에 거래가 있습니다. 디버깅 및 충돌에 대한 질문을 제기하는 것이 싫습니다 . 보통 내가 직접 처리하지만 이미 여러 질문본 후에도이 문제를 해결할 수 없기 때문 입니다.

좋아, 여기에 문제가 있습니다.이 스택 추적으로 내 앱이 무작위로 켜지고 꺼지는 것을 찾습니다.

*** -[ViewController respondsToSelector:]: message sent to deallocated instance 0x1e5d2ef0

어디 ViewController가끔 내 코드가 충돌 장소를 다양 할 수있다 NO의 특정 관련성을 ViewController하고 자신하지 않거나 전화.

또한 콘솔 추적을 얻기 위해 Zombies를 활성화했습니다. 그렇지 않으면 콘솔 인쇄가 전혀 표시되지 않고 다음 objc_msgSend과 같은 결과 만 얻을 수 있습니다. 이는 릴리스 된 내용을 메시징하고 ​​있음을 의미합니다. 하지만 그게 어디인지 모르겠어요 ... 정말 꼼짝 못했어요! 보통 나는 항상 내 크래시를 디버그하기 때문에 나는 이것에 정말로 붙어 있습니다.

다시 말하지만, 이것은 다른 시간에, 켜고 끄는 다른 장소에서 충돌합니다. 그리고 충돌 장소는 거의 없습니다 받는 관련성을 ViewController. 그리고 저는 이것이 매우 혼란 스럽습니다.

내 코드가 필요합니까? 나는이 많은 파일을하고 다른 장소에서 충돌되기 때문에, 내 코드를 배포하는 것은 엉망이 될 것이다!

운없이 상징적 인 중단 점을 추가하려고했는데 iOS 용 Instruments 응용 프로그램에서는 Zombies를 사용할 수 없습니다. 지원하지 않는 아키텍처 프레임 워크가 있으므로 시뮬레이터에서 앱을 실행할 수 없습니다.

모두 감사합니다 ...


이 질문
self

뷰로 전환하는 방식이 일관 적이라고 가정하면 한두 가지 예를 보여줄 수 있습니다. 표준 push / presentViewController 호출을 수행하는 경우 괜찮을 것입니다.하지만 여기에서 뷰 컨트롤러 할당 / 초기화와 같은 작업을하는 많은 사람들이 있지만 푸시 / 프레젠테이션을 수행하지 않고 컨트롤러의 하위보기로보기. 임의의 예입니다. 하지만 코드 없이는이를 진단 할 수 없습니다. 몇 가지 스 니펫이 무슨 일이 일어나고 있는지 파악하는 데 도움이되기를 바랍니다.
Rob

기호 중단 점을 활성화하는 것은 어떻습니까? 이러한 추가 시도 wiki.zemingo.com/index.php?title=Symbolic_Breakpoints을
Stavash

@RobertRyan 나는 presentModalViewController를 사용하고, 나는 그것을 subview로 추가하지 않는다
MCKapur

제 경우에는 자식 뷰 컨트롤러에 webView가 포함되어 있었고 자식 VC는 webView의 scrollView에 대한 대리자였습니다. dealloc / viewWillDisappear 중에 델리게이트 참조를 수동으로 제거해야하거나이 충돌이 발생했습니다. 누군가에게 도움이되기를 바랍니다.
Dermot

답변:


169

Instruments 를 사용 하여 할당 취소 된 인스턴스 오류를 추적합니다. 애플리케이션 ( Cmd ⌘+ I)을 프로파일 링 하고 Zombies 템플릿을 선택합니다 . 응용 프로그램이 실행 된 후 충돌을 시도하십시오. 다음과 같은 결과를 얻을 수 있습니다.

여기에 이미지 설명 입력

팝 오버에서 주소 옆에있는 화살표를 클릭하면 할당이 취소 된 후 호출 된 개체가 표시됩니다.

여기에 이미지 설명 입력

이제 변경된 모든 호출이이 개체의 보유 수를 확인해야합니다. 이는 유지 / 해제 메시지를 직접 전송하고 자동 해제 풀을 비우거나 NSArray에 삽입하기 때문일 수 있습니다.

RefCt 열에는 작업이 호출 된 후 preserveCount가 표시되고 Responsible Caller 는 해당 작업이 수행 된 클래스 이름과 메서드를 표시합니다. 유지 / 해제를 두 번 클릭하면 계측기가 수행 된 코드 줄을 표시합니다 (작동하지 않는 경우 확장 세부 정보 창 에서 해당 호출을 선택하고 해당 호출을 선택하여 검사 할 수 있습니다 ).

여기에 이미지 설명 입력

이렇게하면 개체의 모든 preserveCount 수명주기 를 검사 할 수 있으며 문제를 즉시 찾을 수 있습니다. 당신이해야 할 일은 최신 릴리스에 대한 누락 된 보유 를 찾는 것입니다 .


3
특히 최신 문제가 아닐 수 있습니다 release. 문제는 어떤 불균형 release. 나는 또한 단순히 retain당신이 포인터를 유지하고 나중에 참조하는 것에 대한 실패가 될 수 있습니다 .
Ken Thomases

1
또한 Zombie 도구 템플릿이 없습니다. Xcode Beta 4.5를 사용하고 있기 때문일 수 있습니다. 그 동안 4.4로 전환 할 것입니다
MCKapur

2
오, 좀비는 iOS 시뮬레이터에서만 제공됩니다. 나는 아이폰 OS 시뮬레이터의 아키텍처를 지원하지 않는 사용 내 프레임 워크와 라이브러리의 일부를 실행할 수 없습니다
MCKapur

작은 메모입니다. 이것은 xcode 5의 새로운 기능에서 가져온 것입니다. "Zombies 악기 템플릿은 Xcode 5에서 향상되었으며 이제 장치에서 사용을 지원합니다. 장치에서 좀비를 사용하려면 iOS 7이 필요합니다." 이 노트는 ... 나와 내 소중한 시간 2 시간을 가져
nickfox

2
이 기기를 연결할 때 앱 충돌을 멈추고 "할당 해제 된 인스턴스로 메시지 전송 됨"오류를 표시 하지 않는다는 것은 무슨 의미 입니까? (환자가 "진단 테스트"를 받으면 "질병"이 사라지는 것과 같습니다.)
Praxiteles

59

비슷한 문제가있었습니다. 제 경우에는 viewController가 navigationController 이벤트를 가져 오는 데 필요했기 때문에 탐색 컨트롤러 대리자로 등록했습니다.

 self.navigationController.delegate = self;

해당 컨트롤러가 할당 해제되었지만 여전히 뷰 컨트롤러의 대리자 일 때 충돌이 발생합니다. 이 코드를 dealloc에 ​​추가해도 효과가 없습니다.

-(void) dealloc
{
    if (self.navigationController.delegate == self)
    {
        self.navigationController.delegate = nil;
    }

dealloc이 호출되는 시점에서 뷰 컨트롤러는 이미 뷰 계층 구조에서 제거되었으므로 self.navigationController는 nil이므로 비교가 실패 할 수 있습니다! :-(

해결책은 실제로 그렇게하기 직전에 뷰 계층 구조를 떠나는 VC를 감지하기 위해이 코드를 추가하는 것이 었습니다. iOS 5에 도입 된 방법을 사용하여 뷰가 언제 팝업되고 푸시되지 않는지 확인합니다.

-(void) viewWillDisappear:(BOOL) animated
{  
   [super viewWillDisappear:animated];
   if ([self isMovingFromParentViewController])
   {
      if (self.navigationController.delegate == self)
      {
           self.navigationController.delegate = nil;
      }
   }
}

더 이상 충돌이 없습니다!


저도 감사합니다-이 게시물을 찾는 데 단 4 시간의 검색이 필요했습니다.
daidai 2014

게시 해 주셔서 감사합니다. 같은 문제가 발생했습니다 ^^
Tyron

사람들은 그러한 성가신 문제에 대한 해결책을 어떻게 찾습니까? 오프 모자 !!
ViruMax

4

해결할 수없는 사람을 위해 다음과 같은 몇 가지 다른 기술이 있습니다.

https://stackoverflow.com/a/12264647/539149

https://stackoverflow.com/a/5698635/539149

https://stackoverflow.com/a/9359792/539149

https://stackoverflow.com/a/15270549/539149

https://stackoverflow.com/a/12098735/539149

Xcode 5에서 Instruments를 실행하려면 프로젝트 팝업-> Edit Scheme ... Profile-> Instrument를 클릭하고 Allocations 또는 Leaks를 선택한 다음 앱을 프로파일 링 한 다음 Instruments를 중지하고 Allocations에서 info 버튼을 클릭하고 "Enable NSZombie Detection"을 클릭합니다. .

그러나 com.apple.main-thread에서 직접 오는 메시지의 경우 아무 것도 표시하지 않을 것입니다.

나는 이것에 대해 두 시간 이상 머리를 두 드렸고 그 대답은 과다 릴리스로 판명되었는데, 범인을 찾을 때까지 무차별 대입으로 내 프로젝트 사본을 주석 처리하여 발견했습니다.

[viewController release];
viewController = NULL;

문제는 릴리스가 변수를 NULL로 설정하지 않는다는 것입니다.

즉, NULL 호출로 설정하면 다시 릴리스되고, refcount를 줄이고 나중에 viewController를 참조하는 변수가 완료 될 때까지 메모리를 해제합니다.

따라서 ARC를 활성화하거나 프로젝트가 릴리스 또는 NULL을 일관되게 사용하는지 확인하십시오. 내가 선호하는 것은 NULL을 사용하는 것이다. 왜냐하면 좀비를 참조 할 기회가 없기 때문에 개체가 풀린 곳을 찾기가 더 어려워지기 때문이다.


4

어제 iOS에서 같은 문제를 만났습니다. App "About"하위보기에서 IAP를 만들고 "About"viewDidLoad에 Transaction Observer를 추가했습니다. 처음 구매할 때 문제 없습니다. 메인 창으로 돌아가서 다시 구매할 서브 뷰에 대해 입력 한 후 "할당 해제 된 인스턴스로 메시지 전송"문제가 발생하고 앱이 충돌했습니다.

- (void)viewDidLoad
{
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];                                           object:nil];
}

dealloc에서 Transaction Observer를 제거하면 문제가 해결됩니다.

- (void)dealloc
{
    // Even though we are using ARC, we still need to manually stop observing any
    // NSNotificationCenter notifications.  Otherwise we could get "zombie" crashes when
    // NSNotificationCenter tries to notify us after our -dealloc finished.

    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

그것은 내 런타임 충돌 zombie을 고쳤습니다 ... 나는 인앱 구매에 대한 개체를 얻었습니다. 많은 시간을 파헤친 후 나는 이것을 발견했다 .... 큰 감사합니다.
Mahendra

4

나는 매우 유사한 문제가 있었고 그것이 내비게이션 컨트롤러 델리게이트 세트 때문이라는 것을 알았습니다.

아래는 내 문제를 해결했습니다.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if (self.navigationController.delegate != self) {
        self.navigationController.delegate = self;
    }
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if (self.navigationController.delegate == self) {
        self.navigationController.delegate = nil;
    }
}

감사!! 여기서도 같은 문제였습니다.
pegpeg

2

OS X에서 동일한 문제가 발생했습니다.

이 문제를 해결하려면 - (void)dealloc@SoftwareEvolved가 이미 말했듯 이 충분하지 않습니다 . 그러나 불행히도 - (void)viewWillDisappear버전 10.10 이상에서만 사용할 수 있습니다.

내 NSViewController 하위 클래스에 모든 좀비 위험 참조를 nil로 설정하는 사용자 지정 메서드를 도입했습니다. 제 경우에는 NSTableView속성 ( delegatedataSource)이었습니다.

- (void)shutdown
{
  self.tableView.delegate = nil;
  self.tableView.dataSource = nil;
}

그게 다야. 수퍼 뷰에서 뷰를 제거 할 때마다이 메서드를 호출해야합니다.


2

같은 문제가 있었는데 어떤 델리게이트가 문제를 일으키는 지 찾기가 어려웠습니다. 어떤 줄이나 코드 문도 나타내지 않기 때문에 어떤 식 으로든 시도해 보았습니다.

  1. xib 파일을 열고 파일 소유자에서 "연결 검사기 표시"오른쪽 메뉴를 선택합니다. 델리게이트가 나열되며 의심되는 nil로 설정합니다.
  2. (내 경우와 동일) Textfield와 같은 Property Object가 문제를 일으킬 수 있으므로 대리자를 nil로 설정하십시오.
-(void) viewWillDisappear:(BOOL) animated{

[super viewWillDisappear:animated];

if ([self isMovingFromParentViewController]){

self.countryTextField.delegate = nil;

self.stateTextField.delegate = nil;

}

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