code

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

codestyles 2020. 8. 26. 07:54
반응형

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


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

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

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

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

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

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

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

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

모두 감사합니다 ...


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

여기에 이미지 설명 입력

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

여기에 이미지 설명 입력

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

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

여기에 이미지 설명 입력

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


비슷한 문제가있었습니다. 제 경우에는 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;
      }
   }
}

더 이상 충돌이 없습니다!


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

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

You can run Instruments in Xcode 5 by clicking the project popup->Edit Scheme...Profile ->Instrument and choose Allocations or Leaks, then profile your app, then stop Instruments, click the info button in Allocations and "Enable NSZombie Detection".

However, for the messages that come directly from the com.apple.main-thread, this probably won't reveal anything.

I banged my head on this for over two hours and the answer turned out to be an over-release, which I discovered by commenting out a copy of my project by brute force until I found the culprit:

[viewController release];
viewController = NULL;

The problem is that release doesn't set the variable to NULL.

That means that setting it to NULL calls release again, decrementing the refcount and freeing the memory immediately until later when the variables that reference viewController are finished with it.

So either enable ARC or make sure your project consistently uses release or NULL but not both. My preference is to use NULL because then there is no chance of referencing a zombie but it makes finding where objects are released more difficult.


I had met the same problem in iOS yesterday. I have made IAP in App "About" subview, and I have added Transaction Observer in "About" viewDidLoad. When I purchase for the first time, no problem, but after I back to main window and enter about subview to purchase again, the problem "message sent to deallocated instance" happened, and the App crashed.

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

After I remove Transaction Observer in dealloc, the problem is solved.

- (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];
}

I had a very similar issue and I figured out it was due to navigation controller delegates set.

The below solved my issue,

- (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;
    }
}

Had the same problem in OS X.

To solve this not enough - (void)dealloc method as @SoftwareEvolved already said. But unfortunately - (void)viewWillDisappear is available only on version 10.10 and later.

I introduced custom method in my NSViewController subclass where set all the zombie-dangerous references to nil. In my case that was NSTableView properties (delegate and dataSource).

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

That's all. Each time I'm about to remove view from the superview need call this method.


I had the same Problem.It was difficult to find which delegate cause issue, because it does not indicate any line or code statement So I have try some way, Maybe it becomes helpful to you.

  1. Open xib file and from file's owner, Select "show the connections inspector" right hand side menu. Delegates are listed, set them to nil which are suspected.
  2. (내 경우와 동일) Textfield와 같은 Property Object가 문제를 일으킬 수 있으므로 대리자를 nil로 설정하십시오.
-(void) viewWillDisappear:(BOOL) animated{

[super viewWillDisappear:animated];

if ([self isMovingFromParentViewController]){

self.countryTextField.delegate = nil;

self.stateTextField.delegate = nil;

}

}

참고 URL : https://stackoverflow.com/questions/11170614/viewcontroller-respondstoselector-message-sent-to-deallocated-instance-crash

반응형