Jaka jest różnica między źródłem danych a delegatem?

Mam fundamentalne pytanie związane z wzorcami projektowymi Cocoa Framework.

Jaka jest różnica między delegatem a źródłem danych?

Obie mogą używać deklaracji @protocols, ale niektóre klasy lub frameworki używają delegate, a inne używają datasource.

Wszystko, co mogę zrozumieć z UI/NSTableView to odpowiedź delegate Na zdarzenia związane z interfejsem użytkownika, podczas gdy datasource jest czysto związana z danymi. Ale nie znam żadnych implementacji źródeł danych poza klasami UI Cocoa.

Uwaga:

  • delegat, o którym wspomniałem w tym pytaniu, nie zawsze jest związany z zdarzeniami interfejsu użytkownika.
  • na pytanie o źródło danych udzielono odpowiedzi.
Author: rptwsthi, 2010-02-09

6 answers

Wzorce delegata i datasource są w dużej mierze niezależne i ortogonalne:

Wzorzec delegata jest bardzo powszechny w Cocoa i pozwala delegatowi (dowolnej instancji implementującej nieformalny protokół delegata przed OS X 10.6 lub formalnym delegatem @protocol w wersji 10.6 i późniejszej) modyfikować zachowanie instancji obiektu. Ten wzorzec jest często używany zamiast podklasowania: zamiast podklasowania klasy w celu zmiany jej zachowania, dostarczasz delegata, który odpowiada na odpowiednie metody. Klasy, które używają delegatów, wysyłają wiadomości do swojego delegata podczas zakontraktowanych wydarzeń. API między klasą A delegatem jest definiowane przez klasę i jest różne dla każdej klasy, która używa wzorca, ale API zazwyczaj składa się z komunikatów pytających delegata, jak obsłużyć dane zdarzenie. Jedną z zalet wzorca delegatów nad podklasą jest to, że klasa może implementować wiele protokołów delegatów, pozwalając jej instancjom działać jako delegat dla wielu klas. Podobnie, instancja obiektu może być delegatem dla wielu innych obiektów (stąd większość API delegatów przekazuje obiekt jako pierwszy argument do każdej wiadomości w API). Wzorzec delegata nie jest tak powszechny w innych frameworkach interfejsu użytkownika (chociaż Qt używa wzorca delegata w swoim modelu/widoku) i jest nie taki sam jak delegaty.Net/CLR, które są zasadniczo typowanymi wskaźnikami funkcji.

Wzorzec źródła danych jest często używany przez podklasy NSView w Cocoa, które mają złożone dane o stanie takich jak NSBrowser, NSTableView, NSOutlineView itp. Protokół źródła danych definiuje API, którego instancje tych (i innych) klas mogą używać do wyświetlania danych w widoku. Chociaż architektury wiązań NSController i Cocoa zastąpiły wiele zastosowań wzorca źródła danych, wciąż jest on powszechny i bardzo wydajny. Podobnie jak opisany powyżej wzorzec delegata, część jego mocy pochodzi z obiektu mogącego działać jako źródło danych dla wielu instancji wykorzystujących źródło danych (i prawdopodobnie nawet instancje wielu klas, które mają różne protokoły źródeł danych). Wzorzec źródła danych jest powszechnie używany w innych frameworkach interfejsu użytkownika, takich jak Qt (w modelu/widoku, gdzie model jest analogiczny do źródła danych) i WPF/Silverlight (gdzie źródło danych może być bliżej analogiczne do modelu widoku).

 34
Author: Barry Wark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-09 21:55:57

Źródło danych dostarcza dane, delegat dostarcza zachowanie.

W MVC, Źródło danych znajduje się w warstwie modelu, a delegat w warstwie kontrolnej.

Właściwie, po namyśle, źródłem danych jest zwykle kontroler, który jest niżej, bliżej modelu. Nigdy nie używałem modelu jako źródła danych.

 49
Author: kubi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-09 20:04:57

Załóżmy, że masz 3 tableviews. Dla psów, kotów i ptaków. Stuknięcie w każdą komórkę wyświetli nowy ekran z powiększonym zdjęciem.

Aby to zaprojektować, musisz wymyślić 3 oddzielne źródła danych dla psów, kotów i ptaków. Zasadniczo potrzebujesz trzech tablic.

Nie potrzebujesz jednak 3 delegatów tableview. Ponieważ zachowanie podglądów tabel jest takie samo. Wszystkie one po prostu biorą present a viewController i wypełniają go interfejsem. Jest to prawdą tylko wtedy, gdy delegujesz napisany w sposób ogólny, tzn. w delegacie nie ma kodu specyficznego dla psa, kota lub ptaka.

Powiedział, że można wyodrębnić psa, kota, ptaka ze źródła danych, ale moja odpowiedź była tylko wymyślonym przykładem. Niektóre obiekty niestandardowe są zbyt złożone, aby używać tej samej struktury, stąd potrzeba posiadania 3 źródeł danych.

Stara odpowiedź:

Zanim odpowiesz na pytanie, musisz lepiej zrozumieć wzór projektu delegacji: Zacznę od pytania:

Przez domyślnie Widok TableView wygląda tak:

Tutaj wpisz opis obrazka

Skąd UITableView wie, ile komórek ma zaprezentować? co prezentować w każdej komórce?

    Sama nie wie.
  • prosi inną klasę, aby informowała ją o liczbie komórek i o tym, jaką komórkę zwrócić ( co cellimage,celltitle, cellsubtitle, itp.) wartości dla siebie. Zwykle widzisz tableView (delegowanie klasy) wewnątrz kontrolera ViewController (delegat Klasa)
  • ta koncepcja jednej klasy pytającej drugą jest znana jako delegacja!

Teraz, gdy wiesz, co to jest Delegacja, aby odpowiedzieć na rzeczywiste pytanie OP:

To przede wszystkim ogromna kwestia różnic semantycznych.
Jeśli masz tylko używać (nie tworzyć własnego protokołu) delegatów i źródeł danych Fundacji, to naprawdę nie ma to dla ciebie znaczenia. Jeśli jednak zamierzasz pisać niestandardowe protokoły, zrozumienie ich pomoże Ci lepiej pisz (a przy większym znaczeniu Czytaj, refraktor) kod.

Z punktu widzenia programisty, obie zajmują się interakcją między klasą delegat-ing a klasą delegat.

Źródło Danych

Źródło danych jest prawie identyczne z delegatem. Różnica polega na związek z obiektem delegującym. Zamiast być delegowana Kontrola interfejsu użytkownika, przekazywane jest źródło danych kontrola danych. Delegowanie obiekt, zazwyczaj obiekt widoku taki jako widok tabeli, zawiera odniesienie do źródła danych i czasami pyta go o dane, które powinien wyświetlić. Źródło danych, jak delegować, musi przyjąć protokół i wdrożyć co najmniej wymagane metody tego protokołu. Źródła danych są odpowiedzialne za zarządzanie pamięć obiektów modelu, które przekazują do delegującego widoku.

W kategoriach laika:

DataSource zajmuje się głównie czym i zazwyczaj robi to rzeczy po inicjalizacji . Delegate zajmuje się głównie Jak i feeds masz kilka parametrów, aby dać pewne zachowanie, czyli jeśli użytkownik kliknął to... co powinno się stać? jeśli zwinęli...co powinno się stać?

Jako przykład dla tableView:

DataSource
Co ma w sobie? Jaką celę prezentuję? cellForRowAtIndexPath.
Jaki jest tytuł sekcji? titleForHeaderInSection Ile to komórek? numberOfRowsInSection I dlatego zwykle return wartości. Dla delegatów częściej jest to typ void.


Metody Datasource

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell // return a cell ie UITableViewCell
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int // return a number ie an Int
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? // return the title ie a String  

Metody Delegowania

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)

oczywiście wybrałem wybiórczo, ponieważ niektóre metody datasource nie zwracają, a niektóre metody delegatów zwracają


Delegat
Co powinienem zrobić/jakiej "formy zachowania" powinienem użyć po zakończeniu wyświetlania stopki, czy chcesz, żebym wyświetlał alert?didEndDisplayingFooterView

Am I będziesz miał accessoryType, który daje komórce dodatkowe funkcje? accessoryTypeForRowWithIndexPath

 13
Author: Honey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-26 16:41:05

Z mojego punktu widzenia, {[0] } jest obiektem, który nie wie, gdzie są dane, dlatego powinieneś je podać. Na przykład informowanie obiektu, ile elementów w kolumnie.

A Delegate, która jest częścią, którą obiekt Ci pokazuje, musi być zaimplementowana przez Twoją klasę, ponieważ obiekt wie, gdzie są dane, ale nie wie, jak je poprawnie wykorzystać.

 7
Author: lukenothing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-01 12:56:18

Żeby było krótko:

Delegate odnosi się do działań UI i Użytkownika przeciwko komórkom i tabeli.

Popularne metody: willSelectRow, didSelectRow, willDisplay, heightForRow, willBeginEditingAt

Źródło danych zajmuje się edycją, populacją i wyświetlaniem danych na tableview.

Common methods canEditRowAt, commit, titleForHeaderInSection, cellForRowAt, numerofsections, sectionIndexTitles

 4
Author: Modesto Cabrera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-03 11:03:38

Oba są protokołem, teraz głównym założeniem Protokołu jest zachowanie uniwersalnej praktyki kodowania, lub tej samej praktyki kodowania dla wszystkich(według mojego zrozumienia). Załóżmy, że tworzę tableView Bez UITableViewDataSource & UITableViewDelegate , stworzyłbym tableView w taki sposób, że nie chcesz. W tym miejscu pojawia się Protocol, apple stworzyło jakiś zestaw reguł lub protocol i każdy musi tego przestrzegać. Teraz DataSource & Delegate są oczywiście Protocol , widząc nazwę można zrozumieć DataSource zajmuje się czymś w rodzaju numberOfRowsInSection, cellForRowAtIndexPath, numberOfSections of tableView where some kind of data is being taken / processed, and Delegates are diselectrow, willSelectRow, heightForRow itd tableView, gdzie wiąże się z jakąś zmianą/akcją interfejsu użytkownika. Więc to tylko konwencja nazewnictwa nic hipotetycznego, aby utrzymać zadanie oddzielnie. Jak powiedział wcześniej @kubi: źródło danych dostarcza dane, delegat dostarcza zachowanie.

 2
Author: Arafin Russell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-07 19:06:07