W mojej małej aplikacji na iPada mam funkcję "języka przełączania", która używa obserwatora. Każdy kontroler widoku rejestruje się wraz z moim obserwatorem podczas jego viewDidLoad:
.Niestandardowe dealloc i ARC (Objective-C)
- (void)viewDidLoad
{
[super viewDidLoad];
[observer registerObject:self];
}
Gdy użytkownik kliknie przycisk „Zmień język”, nowy język jest przechowywany w moim modelu i obserwator został powiadomiony i wywołuje selektor updateUi:
na statutową obiektów.
Działa to bardzo dobrze, z wyjątkiem sytuacji, gdy mam kontrolerów widoku w kontrolce TabBarController. Dzieje się tak, ponieważ po załadowaniu paska kart pobiera ikony kart ze swoich kontrolerów podrzędnych bez inicjowania widoków, dlatego viewDidLoad:
nie jest wywoływana, więc te kontrolery widoku nie otrzymują powiadomień o zmianie języka. Z tego powodu przeniosłem swoje wywołania registerObject:
do metody .
Powrót, gdy użyłem viewDidLoad:
do zarejestrowania się z moim obserwatorem, użyłem viewDidUnload:
do wyrejestrowania. Odkąd teraz rejestruję się w init
, ma sens, aby wyrejestrować się w dealloc
.
Ale tu jest mój problem. Kiedy piszę:
- (void) dealloc
{
[observer unregisterObject:self];
[super dealloc];
}
otrzymuję ten błąd:
ARC forbids explicit message send of 'dealloc'
Ponieważ muszę zadzwonić [super dealloc]
celu zapewnienia superklasy oczyścić prawidłowo, ale ARC zabrania, jestem teraz zakleszczony. Czy istnieje inny sposób na uzyskanie informacji, kiedy mój obiekt umiera?
Na marginesie - sytuacja jak może to spowodować wyciek pamięci, który nie byłby widoczny w narzędziu Wycieki. Jeśli moduł danych zachowuje odwołanie do obserwatora (co jest domyślną rzeczą w ARC, nawet w przypadku ivars), dealloc nigdy nie zostanie wywołany, ponieważ liczba zatrzymań będzie większa niż zero. Dlatego konieczne może być ręczne wyrejestrowanie obserwatora, aby umożliwić wywołanie dealloc w pierwszej kolejności. –
Zaimplementowałem coś podobnego dla opcji prawej i lewej ręki. Jedynym VC wymagającym wiadomości jest aktualnie wyświetlany. Inni patrzą na model w viewDidLoad lub viewDidAppear, aby dokonać zmian w interfejsie. Może coś takiego będzie działało lepiej. –
@BlazejCzapp od kiedy używa UITabBarController, i powiedzmy, że UITabBarController zawsze będzie zawierał referencje do zarejestrowanego kontrolera (jak myślę, jest w przypadku jego "potomnych" kontrolerów), czy wyciek pamięci nadal będzie problemem? Nie widzę, kiedy będzie przydzielony zarejestrowany kontroler. Dzięki – Objectif