이것은 내 패턴입니다.대리인에게 인스턴스가 더 이상 필요하지 않음을 올바르게 알리는 방법은 무엇입니까?
1) SpecialView는 MessageView를 만들고 강력한 참조를 보유합니다.
2) 사용자가 MessageView의 버튼을 탭하여 페이드 아웃시킵니다. 그런 다음 MessageView는 그것이 완전히 사라져 버린 대리자 인 SpecialView를 알립니다.
3) SpecialView가 MessageView를 출시합니다. 내가 다시 바로 MessageView 출시 대리자를 호출하고있어 마지막 줄에서
- (void)fadedOut:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context {
[self.delegate messageViewFadedOut:self]; // delegate releases us...
// self maybe got deallocated... BOOM!
// now what? method of a zombie returns? stack freaks out?
} // does it even return?
:
문제는 이것이다. -fadedOut : finished : context : 코어 애니메이션 didStopSelector 콜백에 의해 호출됩니다.
는 나의 두려움은 MessageView 인스턴스가 즉시 -fadedOut 전에 을 해제 할 예정이다 : 완료 : 컨텍스트 : 매우 불쾌한 임의 버그 옛적에 한 번
의 원인이 완전히 돌아 오래된 베테랑 프로그래머는 말했다 나 : "너가 앉아있는 지점을 절대로 잘라내 지마." 유지 - 오토 릴리즈 춤이 허용되지 않습니다, ARC에서,
- (void)fadedOut:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context {
//[[self retain] autorelease];
[self.delegate messageViewFadedOut:self]; // delegate releases us...
}
그러나 :
그래서 인스턴스가이 메소드가 반환 될 때까지 남아 있는지 확인하기 위해, 나는 대리자를 호출하기 전에 유지-autorlease 댄스를 만든 더 이상 (마이그레이션 도구에서 허용되지 않음) ARC 시스템에 이와 같은 작업을 수행 할 수있는 방법이 없을 것입니다.
그래서 내가 대신이 전략을 내놓았다 :- (void)fadedOut:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context {
[self.delegate performSelector:@selector(messageViewFadedOut:) withObject:self afterDelay:0];
}
이 지연 performSelector 잘하면 방법이 완전히 반환 할 수 있습니다. 내가 아는 한 0의 지연은 셀렉터가 다음 루프 반복에서 즉시 수행되는 것을 보장합니다.
가짜이기도합니다.
다른 개체를 호출 한 메서드가 완전히 반환되기 전에 개체의 할당이 취소 될 가능성이있는 다른 개체에 대한 마지막 참조를 파기하도록 다른 개체에 요청하는이 문제를 올바르게 해결하려면 어떻게해야합니까? 스택 트레이스 좀비 같은 것이있을 수 있습니까?
그리고 ARC에서 어떻게 해결해야합니까?
동의! 그러나 실제 질문은 : 객체 중 하나가 완전히 반환 된 메서드가 있기 전에 객체의 할당을 해제하면 위험 할 수 있습니까? 위의 코드에서 볼 수 있듯이 대리자를 호출 한 후에는 아무 것도 발생하지 않습니다. 그래서 이론적으로 아무런 문제가 없습니다. 런타임을 제외하고 좀비가 돌아오고 있다는 사실에 대해 괴롭힘. – openfrog
오. 아니요, 제가 말할 수있는 한 위험하지 않습니다. 나는 그것을 프로덕션 애플 리케이션에서 직접하고 어떤 부작용도 발생하지 않았다. 나는 방법의 마지막 라인에서만 그것을 할 것이다. 그렇지 않으면'dealloc''d'self에 접근하려고 시도 할 수있는 것이있을 수있다. – darvids0n