Odpowiedzi:
Oprócz tego, co już zostało wskazane, chciałem bardziej szczegółowo omówić logikę stojącą za -viewDidUnload
.
Jednym z najważniejszych powodów, dla których warto ją wdrożyć, jest to, że UIViewController
podklasy zwykle zawierają również odniesienia do różnych podwidoków w hierarchii widoków. Te właściwości mogły zostać ustawione IBOutlets
podczas ładowania z końcówki lub -loadView
na przykład programowo wewnątrz .
Dodatkowa własność widoków podrzędnych polega na tym UIViewController
, że nawet jeśli jego widok zostanie usunięty z hierarchii widoków i zwolniony w celu oszczędzania pamięci, przez który podglądy podrzędne są również zwalniane przez widok, w rzeczywistości nie zostaną one cofnięte, ponieważ UIViewController
sam nadal zawiera własne zaległe zachowując również odniesienia do tych obiektów. Zwolnienie UIViewController
dodatkowej własności tych obiektów gwarantuje, że zostaną one również zwolnione w celu zwolnienia pamięci.
Obiekty, które tutaj zwalniasz, są zwykle odtwarzane i ustawiane ponownie, gdy UIViewController
widok pochodzi re-loaded
ze stalówki lub za pomocą implementacji -loadView
.
Należy również pamiętać, że UIViewController
view
właściwość jest nil
w momencie wywołania tej metody.
Jak mówi dokumentacja :
Jest wywoływana w warunkach małej ilości pamięci, kiedy kontroler widoku musi zwolnić swój widok i wszystkie obiekty skojarzone z tym widokiem, aby zwolnić pamięć.
W tej samej sytuacji dealloc
się nie nazywa. Ta metoda jest dostępna tylko w systemie OS3 i nowszych. Radzenie sobie z tą samą sytuacją w iPhone OS 2.x było prawdziwym bólem!
Aktualizacja z lipca 2015 r . : należy zauważyć, że viewDidUnload
w systemie iOS 6 została wycofana, ponieważ „Widoki nie są już czyszczone w warunkach małej ilości pamięci, więc ta metoda nigdy nie jest wywoływana”. Tak więc, współczesna rada nie polega na tym, aby się tym martwić i używać dealloc
.
Dzieje się tak, ponieważ zazwyczaj ustawiasz @property
as "(nonatomic, retain)"
i jako taki ustawiacz, który jest tworzony dla ciebie, zwalnia bieżący obiekt, a następnie zachowuje argument, tj.
self.property = nil;
... robi coś w rodzaju:
[property release];
property = [nil retain];
Dlatego zabijasz dwa ptaki jednym kamieniem: zarządzanie pamięcią (zwalnianie istniejącego obiektu) i przypisywanie wskaźnika do zera (ponieważ wysłanie jakiejkolwiek wiadomości do wskaźnika zerowego zwróci zero).
Mam nadzieję, że to pomoże.
Pamiętaj, że viewDidUnload
jest to metoda w kontrolerze widoku, a nie w widoku. Metoda widoku dealloc
zostanie wywołana, gdy widok zostanie zwolniony, ale metoda kontrolera widoku dealloc
może zostać wywołana dopiero później.
Jeśli pojawi się ostrzeżenie o małej ilości pamięci, a widok nie jest wyświetlany, co stanie się na przykład za każdym razem, gdy użyjesz UIImagePickerController, aby umożliwić użytkownikowi zrobienie zdjęcia, widok zostanie wyładowany i będzie musiał zostać ponownie załadowany.
Wniosek:
Kontrolery widoku mają właściwość widoku. Zazwyczaj końcówka lub fragment kodu dodaje inne widoki do tego widoku. Dzieje się tak często wewnątrz metody -viewDidLoad, na przykład:
- (void)viewDidLoad {
[super viewDidLoad];
[self createManyViewsAndAddThemToSelfDotView];
}
ponadto plik nib może utworzyć przycisk i dołączyć go do widoku kontrolera widoku.
W systemie iPhone OS 2.2, kiedy -didReceiveMemoryWarning został wywołany z systemu, trzeba było zwolnić coś, aby zwolnić pamięć. Możesz zwolnić widok całego kontrolera widoku, jeśli to ma sens. Lub po prostu duża zawartość zajmująca pamięć.
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
Teraz w nowym OS 3.0 jest metoda -viewDidUnload, która zostanie wywołana z systemu, gdy widok zostanie wyładowany z powodu małej ilości pamięci (proszę mnie poprawić: kiedy dokładnie to się wywoła?)
-viewDidUnload służy do zwalniania wszystkich obiektów, których właścicielem był zarówno sam kontroler widoku, jak i widok. Powód: jeśli kontroler widoku przechowuje odwołania do elementów podrzędnych widoku, tj. Przycisku, przywoływane widoki potomne nie zostaną zwolnione, ponieważ ich liczba zachowań wynosi> = 1. Po ich zwolnieniu w -viewDidUnload można je zwolnić z pamięci.
Przestarzały widok Apple ViewWillUnload, teraz powinieneś użyć didReceiveMemoryWarning lub dealloc, aby zwolnić swoje objetcs.
W systemie iOS 6 metody viewWillUnload i viewDidUnload UIViewController są teraz przestarzałe. Jeśli używasz tych metod do udostępniania danych, użyj zamiast tego metody didReceiveMemoryWarning. Możesz również użyć tej metody, aby zwolnić odwołania do widoku kontrolera widoku, jeśli nie jest używany. Zanim to zrobisz, musisz sprawdzić, czy widoku nie ma w oknie.
Jeśli kontroler widoku zostanie pobrany ze stosu kontrolera nawigacji i nie zostanie zachowany nigdzie indziej, zostanie cofnięty, a dealloc zostanie wywołana zamiast viewDidUnload. Powinieneś zwolnić widoki utworzone w loadView w dealloc, ale nie jest konieczne ustawianie zmiennych na nil, ponieważ wkrótce po wywołaniu dealloc zmienne już nie będą istnieć.