작은 iPad 앱에는 관찰자를 사용하는 "스위치 언어"기능이 있습니다. 모든보기 컨트롤러는 내 관찰자에게 자신을 등록합니다 viewDidLoad:
.
- (void)viewDidLoad
{
[super viewDidLoad];
[observer registerObject:self];
}
사용자가 "언어 변경"버튼을 누르면 새 언어가 내 모델에 저장되고 관찰자에게 통지되고 updateUi:
등록 된 객체 에서 선택기를 호출 합니다.
이것은 TabBarController에 뷰 컨트롤러가있는 경우를 제외하고는 매우 잘 작동합니다. 이는 탭 막대가로드 될 때 뷰를 초기화하지 않고 자식 컨트롤러에서 탭 아이콘을 가져 오기 때문에 viewDidLoad:
호출되지 않으므로 뷰 컨트롤러가 언어 변경 알림을받지 않기 때문입니다. 이로 인해 registerObject:
호출을 init
메서드 로 옮겼습니다 .
viewDidLoad:
관찰자로 등록 할 때 다시 등록 viewDidUnload:
을 취소했습니다. 내가 지금 등록하고 있기 때문에 init
에 등록을 취소하는 것이 좋습니다 dealloc
.
그러나 여기 내 문제가 있습니다. 내가 쓸 때 :
- (void) dealloc
{
[observer unregisterObject:self];
[super dealloc];
}
이 오류가 발생합니다.
ARC는 'dealloc'의 명시적인 메시지 전송을 금지합니다.
[super dealloc]
수퍼 클래스가 올바르게 정리되도록 호출해야 하지만 ARC는이를 금지하므로 이제 막혔습니다. 물건이 죽을 때 알림을받는 다른 방법이 있습니까?
참고로-이와 같은 상황은 메모리 누수를 일으킬 수 있으며 누출 도구에는 표시되지 않습니다. dataModel이 옵저버에 대한 참조를 유지하는 경우 (ivar의 경우에도 ARC에서 기본 사항 임) 유지 횟수가 0보다 크므로 dealloc이 호출되지 않습니다. 따라서 처음에 dealloc을 호출 할 수 있도록 옵저버를 수동으로 등록 취소해야 할 수도 있습니다.
—
Błażej Czapp
오른 손잡이와 왼손잡이 옵션에 비슷한 것을 구현했습니다. 메시지가 필요한 유일한 VC는 현재 표시된 것입니다. 다른 사람들은 viewDidLoad 또는 viewDidAppear에서 모델을보고 인터페이스를 변경합니다. 아마도 이와 같은 것이 더 잘 작동 할 것입니다.
—
더그 왓킨스
@BlazejCzapp는 UITabBarController를 사용하고 있기 때문에 UITabBarController가 항상 등록 된 컨트롤러에 대한 참조를 보유한다고 가정합니다 ( '자식'컨트롤러의 경우와 같이) 메모리 누수가 여전히 문제가됩니까? 등록 된 컨트롤러가 언제 할당되는지 알 수 없습니다. 감사합니다
—
Objectif