W tej chwili uczę się programowania na iOS, a jedną z koncepcji, dla której naprawdę trudno mi się oprzeć, jest delegacja. Co to jest? Dlaczego i jak się go stosuje? Jaka jest zaleta? Techniczne pisanie z książki, którą czytam, sprawia, że trudno ją zrozumieć.
11
Odpowiedzi:
Aby zrozumieć
delegates
, musisz zrozumiećprotocols
.A
protocol
jest jak umowa serwisowa. Kiedy obiekt (najczęściejUIViewController
podklasa, ale nie zawsze) podpisuje tę umowę, mówi: „Jestem zainteresowany logiką, aby poprzeć przesłaną mi wiadomość”. Jest to podobne doNSNotificationCenter
zapisywania się na pewien poziom zainteresowania, z tą różnicą, że obiekt, który korzysta z delegacji, może mieć tylko jedendelegate
na raz, ponieważ wiele obiektów może zarejestrować się na taki sam poziomNSNotification
.Apple szeroko rozpowszechnia delegowanie uprawnień. Coraz częściej jednak Apple przenosi wiele swoich interfejsów API
blocks
, które są podobne docallbacks
innych języków.Biorąc to pod uwagę, delegacja pomaga utrzymać MVC, nawet jeśli twierdzę, że delegacja jest sama w sobie wzorcem projektowym. Pomaga oddzielić modele od sterowników. Tak jak w przykładzie Johna Cartwrighta,
UITableView
umie on wyświetlać wiersze i sekcje. Wie, jak wykorzystać ponownieUITableViewCells
ze względu na wydajność. Zna wszystkie inne rzeczy, któreUIScrollView
zna. Ale nie wie, które komórki wyświetlić. Nie wie, co wypełnić tymi komórkami. Nie wie, które komórki użyć ponownie dla danegoNSIndexPath
. W każdym razie to naprawdę powinno być zadaniem kontrolera. Delegowanie umożliwia widokowi tabeli odciążenie tej logiki braku widoku na obiekt, który i tak powinien ponosić tę odpowiedzialność.Co więcej, nie jesteś zamknięty w jednym uczestniku przez cały okres życia obiektu. Możesz bardzo łatwo mieć wiele źródeł danych dla danego
UITableView
i przełączać je w czasie wykonywania w razie potrzeby.Z jednej strony delegowanie świetnie nadaje się do dostarczania danych i reagowania na interakcje z obiektem. Zobaczysz go w wielu klasach UIKit taka
UITableView
,UIPickerView
,UICollectionView
, etc.Ale delegowanie jest również bardzo przydatne, gdy chcesz przekazywać informacje między obiektami. Możesz bardzo łatwo tworzyć własne protokoły i rejestrować własne obiekty, aby ich przestrzegać. Ponadto metody protokołów są
@required
domyślnie, ale można określić niektóre z nich@optional
. To może dać ci niezłą elastyczność, jeśli jej potrzebujesz. Załóżmy, że masz nadrzędny kontroler widoku i kontroler widoku potomnego. Być może używasz do tego nowego interfejsu API Containment. Zazwyczaj, jeśli musisz przekazać informacje od rodzica do dziecka, robisz to z właściwością. Gotowe. Ale co, jeśli musisz przekazać rodzicowi informacje od dziecka? Może coś się zmienia u dziecka i musisz powiadomić rodzica. Pewnie, możesz zrobić KVO na niektórych wartościach. Ale może chcesz wiedzieć, kiedy zostanie naciśnięty przycisk. Wystarczy utworzyć nowy protokół w kontrolerze widoku potomnegoPo stuknięciu przycisku w MyChildViewController, po prostu sprawdź, czy Twój delegat odpowiada na wiadomość delegowaną (jeśli jest to wymagane, a Twój delegat nie implementuje metody,
@optional
nastąpi awaria. Możesz wykonać metodę, jeśli trzeba) i wysłać to:Następnie ustaw delegata swojego MyChildViewController na
self
i zaimplementuj go- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
w nadrzędnym kontrolerze widoku. BUM! Przekazałeś informacje od dziecka do rodzica. Relacja między tymi dwoma obiektami nie musi nawet być tak bliska jak rodzic / dziecko. Jest to umowa serwisowa, więc dopóki rejestracja obiektu utrzyma koniec okazji poprzez wdrożenie wymaganych metod, jesteś złoty!UWAGA: Delegaci powinni być słabi / przypisywać właściwości, w przeciwnym razie przejdziesz do cyklu przechowywania, w którym nie można cofnąć przydziału żadnego obiektu.
Mam nadzieję że to pomoże!
źródło
Delegaci to obiekty, które implementują określone funkcje, gdy nie ma sensu implementować tych funkcji na normalnym obiekcie. Jest to forma zastrzyku zależności.
Konkretnym przykładem jest protokół UITableViewDelegate. Te metody nie mają sensu, aby widok tabeli był implementowany bezpośrednio, ponieważ działania służące do wybierania wiersza widoku tabeli będą różne w każdej aplikacji i być może w każdym widoku tabeli. Delegat ma metodę,
-tableView:didSelectRowAtIndexPath:
dzięki której można utworzyć obiekt, który obsługuje zaznaczanie wierszy bez podklasowania widoku tabeli dla każdej osobnej akcji, którą chcesz zaimplementować.źródło