2011-03-03 10 views
16

Dla programistów iOS delegatów używa się niemal wszędzie.Właściwość "przypisz" i "zatrzymaj" dla delegata

I wydaje się, że musimy użyć „przypisać” zamiast zachować dla delegata jak ten

Powodem jest to, aby uniknąć kołowego WYDANIE pętla Why are Objective-C delegates usually given the property assign instead of retain?

Widziałem dużo kodu i nadal używali "zachowywania". Więc pytanie brzmi: czy nadal będziemy mieć problem z pętlą kołową, jeśli użyjemy retain dla delegata?

Dzięki

Odpowiedz

26

documentation mówi:

oporowe obiektu tworzy silne odniesienia, a obiekt nie może być zwalniane aż wszystkie jego mocne referencje są uwalniane. Jeśli dwa obiekty zachowują się nawzajem, ani obiekt kiedykolwiek zostanie dealokowane ponieważ połączenie między nimi nie może być uszkodzony

Jako przykład rozważmy UITableViewController który implementuje protokół UITableViewDelegate. UITableView jest zachowywany przez kontroler widoku, chociaż UITableView nie zachowuje delegata.

Jak wspomniano w powyższym dokumencie, UITableViewController zakończy transakcję dopiero po wydaniu wszystkich silnych referencji. Ponieważ UITableView, który ma UItableViewController jako delegata, nie zachowuje go, gdy właściciel UItableViewController wywoła na nim zwalnianie, licznik zatrzymania zostanie ustawiony na zero, a metoda dealloc zostanie wywołana.

Teraz wyobraź sobie, że UITableView zachowuje swojego pełnomocnika. UITableViewController będzie mieć wartość zatrzymania co najmniej +2. Jeden z jego właścicielem, a drugi z UITableView. Kiedy właściciel UITableViewController wywoła na nim zwolnienie, licznik zatrzymań zostanie zwiększony do +1, a nie do zera zgodnie z oczekiwaniami, a więc metoda dealloc nie zostanie wywołana, dopóki liczba zatrzymań nie osiągnie wartości zero. Aby osiągnąć zero, UITableViewController musiałby zwolnić swój UITableView, który następnie zwolniłby jego delegata (UITableViewController). Ponieważ kontroler UITableViewController będzie wyświetlał tylko swój widok (UITableView), gdy deallocing tej chwili nigdy nie nastąpi, ponieważ liczba zatrzymań nie spadnie poniżej +1.

(nie bierzmy pod uwagę ostrzeżeń pamięci i innych możliwych przypadków ... Właśnie zobaczyłem, że ViewController/View nie jest najlepszą opcją dla tego przykładu, ale napisałem już za dużo :))

Czy to ma sens?

+0

Tak, zrób wielki sens i dziękuję bardzo! W twoim przypadku A to UITableViewController, B to TableView, więc jedynym właściwym sposobem jest użycie "przypisania" dla delegata w TableView. Rozważmy inny wspólny przypadek: A to ViewController, B to inny ViewController, A to nowy B i użyj "retain" dla delegata w B, a także A może zwolnić B, więc w tym przypadku "zatrzymaj" jest w porządku dla delegować w B. Czy to ma sens? – Forrest

+0

Nie rozumiem. Mówisz, że A tworzy B, A używa B jako delegata na coś, a więc A.viewController (zachowaj) = B i A.delegate (przypisz) = B. Lub A jest delegatem na B, a więc A. viewController (retain) = B i B.delegate (assign) = A? Który z nich jest? – vfn

+0

Kontekst o A i B pochodzi z połączenia Dlaczego delegowani z Objective-C zwykle mają przypisaną właściwość zamiast zatrzymywania? – Forrest

Powiązane problemy