Какая разница между источником данных и делегатом?

268
31

У меня есть фундаментальный вопрос, связанный с шаблонами проектирования Cocoa.


Какая разница между делегатом и источником данных?


Оба могут использовать объявление @protocols, но некоторые классы или фреймворки используют delegate, а некоторые другие используют datasource.


Все, что я могу понять из UI/NSTableView, - это delegate отвечать на события, связанные с UI, тогда как datasource имеет чисто отношение к данным. Но я не знаю никаких реализаций источника данных вне классов пользовательского интерфейса Cocoa.


Примечание:


    Делегат, которого я упомянул в этом вопросе, не всегда связан с событиями пользовательского интерфейса.
    Ответ на вопрос источника данных.

спросил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
1
Решение
280

Источник данных предоставляет данные, делегат поставляет это поведение.


В MVC, источник данных находится на уровне модели, а делегат находится на уровне управления.

Собственно, с другой стороны, источником данных обычно является контроллер, который ниже, ближе к модели. Я не думаю, что когда-либо использовал модельный объект в качестве источника данных.

ответил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
251

Элементы делегата и источника данных в значительной степени независимы и ортогональны:


Шаблон делегирования очень распространен в Cocoa и позволяет делегату (любой экземпляр, реализующий неофициальный протокол делегата до OS X 10.6 или формальный делегат @protocol в 10.6 и более поздних версиях), чтобы изменить поведение объекта пример. Этот шаблон часто используется вместо подкласса: вместо подкласса класса для изменения его поведения вы предоставляете делегат, который отвечает на соответствующие методы. Классы, которые используют делегаты, отправляют сообщения своему делегату по связанным событиям. API между классом и делегатом определяется классом и отличается для каждого класса, который использует шаблон, но API обычно состоит из сообщений, запрашивающих у делегата, как обрабатывать определенное событие. Одним из преимуществ шаблона делегирования по подклассу является то, что класс может реализовывать несколько протоколов делегатов, позволяя его экземплярам выступать в роли делегата для нескольких классов. Точно так же экземпляр объекта может быть делегатом для нескольких других объектов (поэтому большинство делегатов API передают объект в качестве первого аргумента для каждого сообщения в API). Шаблон делегирования не так распространен в других инфраструктурах пользовательского интерфейса (хотя Qt использует шаблон делегата в своей структуре Model/View) и не совпадает с делегатами .Net/CLR, которые по сути являются типизированными указателями функций.

Шаблон источника данных часто используется подклассами NSView в Cocoa, которые имеют сложные данные состояния, такие как NSBrowser, NSTableView, NSOutlineView и т.д. Протокол источника данных определяет API, что экземпляры этих (и других), которые могут использоваться для отображения данных в представлении. Хотя архитектуры NSController и Cocoa Bindings заменяли множество применений шаблона источника данных, они все еще распространены и очень мощны. Подобно описанному выше шаблону делегата, часть его мощности исходит от объекта, который может выступать в качестве источника данных для нескольких экземпляров, использующих источник данных (и, возможно, даже экземпляров нескольких классов, имеющих разные протоколы источника данных). Шаблон источника данных обычно используется в других инфраструктурах пользовательского интерфейса, таких как Qt (в структуре Model/View, где модель аналогична источнику данных) и WPF/Silverlight (где источник данных может быть более близким к модели представления).

ответил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
158

Прежде чем ответить на вопрос, вы должны лучше понять схему проектирования делегирования. Позвольте мне начать с вопроса:

По умолчанию TableView выглядит так:

enter image description here

Как UITableView знает, сколько ячеек представить? что подарить в каждую клетку?

    Само по себе это не знает. Он просит другой класс проинформировать его о количестве ячеек и о том, какую ячейку вернуть (какие cellimage, celltitle, cellubtitle и т. Обычно вы видите tableView (делегирующий класс) внутри ViewController (делегируемый класс) Эта концепция, когда один класс просит другого, называется делегированием!

Теперь, когда вы знаете, что такое делегация, ответьте на актуальный вопрос ФП:

Это в основном ОГРОМНЫЙ вопрос семантических различий.
Если вы используете только (не для создания собственного протокола) базовые делегаты и источники данных, тогда это действительно не имеет значения для вас. Однако, если вы намереваетесь писать собственные протоколы, то понимание их поможет вам лучше написать (и, что важнее, прочитать, рефрактор) код.

С точки зрения разработчика, они оба имеют дело с взаимодействием между классом delegat- и классом делегата.

Источник данных

Источник данных практически идентичен делегату. Разница заключается в отношениях с делегирующим объектом. Вместо делегированного управления пользовательским интерфейсом источнику данных делегируется управление данными. Делегирующий объект, как правило, объект представления, такой как табличное представление, содержит ссылку на свой источник данных и иногда запрашивает у него данные, которые он должен отобразить. Источник данных, как и делегат, должен принять протокол и реализовать как минимум требуемые методы этого протокола. Источники данных отвечают за управление памятью объектов модели, которые они передают представлению делегирования.

С точки зрения непрофессионала:

DataSource имеет дело главным образом с тем, что и обычно делает это после инициализации. Делегирование занимается в основном с тем, как и подает вам некоторые параметры, чтобы дать определенное поведение, т.е. если пользователь нажал это... то, что должно произойти? если они сильно ударили... что должно произойти?

В качестве примера для tableView:

Источник данных
Что у него внутри? Какую клетку я представляю? cellForRowAtIndexPath.
Как называется раздел? titleForHeaderInSection Сколько они клеток? numberOfRowsInSection И поэтому вы обычно возвращаете значения. Для делегатов чаще встречается тип void.

Методы источника данных

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

Методы делегирования

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

Я явно выбрал выборочно, так как некоторые методы источника данных не возвращаются, а некоторые методы делегата возвращают

делегат
Что я должен делать/какую "форму поведения" я должен использовать после завершения отображения нижнего колонтитула, вы хотите, чтобы я выдал предупреждение? didEndDisplayingFooterView

Я собираюсь иметь accessoryType, который дает клетке некоторые дополнительные функции? accessoryTypeForRowWithIndexPath

ответил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
130

С моей точки зрения, DataSource - это объект, который не знает, где находятся данные, и, следовательно, вы должны его предоставить. Например, чтобы указать объекту, сколько элементов в столбце.


A Delegate, который является частью, которую объект показывает вам, должен быть реализован вашим классом, потому что объект знает, где находятся данные, но он не знает, как правильно его использовать.

ответил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
87

Чтобы сделать это коротким:

Делегат относится к пользовательскому интерфейсу и действиям пользователя против ячеек и таблицы.

общие методы: willSelectRow, didSelectRow, willDisplay, heightForRow, willBeginEditingAt

Источник данных занимается редактированием, заполнением и отображением данных в виде таблицы.

общие методы canEditRowAt, commit, titleForHeaderInSection, cellForRowAt, numberOfSections, sectionIndexTitles

ответил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
44

Оба являются протоколом, и теперь основная цель протокола - сохранить универсальную практику кодирования или одинаковую практику кодирования для всех (насколько я понимаю). Предположим, что я создаю tableView без UITableViewDataSource & UITableViewDelegate, я бы создал tableView таким образом, чтобы вы этого не сделали. Вот где приходит протокол, Apple создала некоторый набор правил или протоколов, и каждый должен следовать этому. Теперь DataSource & Delegate, очевидно, являются Protocol, видя имя, которое, как вы понимаете, DataSource имеет дело с чем-то вроде numberOfRowsInSection, cellForRowAtIndexPath, numberOfSections of tableView, где некоторые виды данных принимаются/обрабатываются, а делегаты - didSelectRow, willSelectRow, heightForRow и т.д. tableView, где их связанные с каким-то изменением пользовательского интерфейса/действия. Так что в соглашении об именах нет ничего гипотетического, чтобы разделить задачу. Как сказал @kubi ранее: источник данных предоставляет данные, а делегат - поведение.

ответил(а) 2021-01-19T17:15:19+03:00 3 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема