cocoa delegates protocols datasource

cocoa - ¿Cuál es la diferencia entre el origen de datos y el delegado?



delegates protocols (5)

Tengo una pregunta fundamental relacionada con los patrones de diseño de los marcos de Cocoa.

¿Cuál es la diferencia entre delegado y fuente de datos?

Ambos podrían usar la declaración de @protocols , pero algunas clases o frameworks están usando delegate , y algunos otros están usando datasource .

Todo lo que puedo entender de UI/NSTableView es que el delegate responda a los eventos relacionados con la interfaz de usuario, mientras que el datasource está puramente relacionado con los datos. Pero, no conozco ninguna implementación de fuente de datos fuera de las clases UI de Cocoa.

Nota:

  • El delegado que mencioné en esta pregunta no siempre está relacionado con eventos de IU.
  • La pregunta de fuente de datos ha sido respondida.

Antes de responder la pregunta, debe comprender mejor el patrón de diseño de la delegación: Permítame comenzar con una pregunta:

Por defecto, un TableView es así:

¿Cómo sabe una UITableView cuántas celdas presentar? ¿Qué presentar en cada celda?

  • Por sí mismo, no sabe.
  • Pide a otra clase que le informe sobre el número de celdas y qué celda devolver (qué imagen de celda, título de celda, número de subtítulo, etc.) se valora a sí mismo. Por lo general, se ve un tableView (clase de delegación) dentro de un ViewController (clase de delegado)
  • ¡Este concepto de una clase preguntando a otra se conoce como delegación!

Ahora que sabe qué es Delegación, para responder la pregunta real del PO:

Es principalmente un ENORME tema de diferencias semánticas.
Si solo va a utilizar (no crear su propio protocolo) los delegados de la fundación y las fuentes de datos, realmente no tiene importancia para usted. Sin embargo, si tiene la intención de escribir protocolos personalizados, comprenderlos lo ayudará a escribir mejor (y con un código de lectura, refractor de mayor importancia).

Desde el punto de vista de un desarrollador, ambos se ocupan de la interacción entre la clase delegante y la clase delegada.

Fuente de datos

Una fuente de datos es casi idéntica a un delegado. La diferencia está en la relación con el objeto delegante. En lugar de tener el control delegado de la interfaz de usuario, una fuente de datos es un control de datos delegado. El objeto delegado, normalmente un objeto de vista como una vista de tabla, contiene una referencia a su origen de datos y ocasionalmente le pide los datos que debería mostrar. Una fuente de datos, como un delegado, debe adoptar un protocolo e implementar al menos los métodos requeridos de ese protocolo. Las fuentes de datos son responsables de administrar la memoria de los objetos modelo que otorgan a la vista delegante.

En términos de Layman:

DataSource se ocupa principalmente de qué y, por lo general, es material al momento de la inicialización . Delegate se ocupa principalmente de cómo y le da algunos parámetros para dar un comportamiento determinado, es decir, si el usuario hizo clic en esto ... ¿qué debería pasar? si se pasaron ... ¿qué debería pasar?

Como un ejemplo para tableView:

Fuente de datos
¿Qué tiene dentro? ¿Qué tipo de celular estoy presentando? cellForRowAtIndexPath .
¿Cuál es el título de la sección? titleForHeaderInSection ¿Cuántas celdas son? numberOfRowsInSection Y, por lo tanto, generalmente devuelve valores. Para los delegados, es más común ser de tipo void .

Métodos de origen de datos

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

Delegar métodos

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

Obviamente elegí selectivamente ya que algunos métodos de fuente de datos no regresan y algunos métodos de delegado lo devuelven

Delegar
¿Qué debo hacer / qué ''forma de comportamiento'' debo usar después de terminar la visualización del pie de página, ¿quieres que haga una modificación? didEndDisplayingFooterView

¿Voy a tener accesorioType que le da a la célula algunas características adicionales? accessoryTypeForRowWithIndexPath


Desde mi punto de vista, un DataSource es un objeto que no sabe dónde están los datos y, por lo tanto, debe proporcionarlos. Como decirle a un objeto cuántos elementos en una columna.

La clase debe implementar un Delegate , que es una parte que el objeto le muestra, porque el objeto sabe dónde están los datos, pero no sabe cómo usarlos correctamente.


El origen de datos proporciona los datos, el delegado proporciona el comportamiento.

En MVC , el origen de datos está en la capa de modelo y el delegado está en la capa de control.

En realidad, pensándolo bien, el origen de datos suele ser el controlador que está más abajo, más cerca del modelo. No creo que alguna vez haya usado un objeto modelo como fuente de datos.


Los patrones de delegado y fuente de datos son en gran parte independientes y ortogonales:

El patrón de delegado es muy común en Cocoa y permite que un delegado (cualquier instancia que implemente el protocolo de delegado informal anterior a OS X 10.6, o el delegado formal @protocol en 10.6 y posterior) modifique el comportamiento de una instancia de objeto. Este patrón se usa a menudo en lugar de crear subclases: en lugar de subclasificar una clase para cambiar su comportamiento, se proporciona un delegado que responde a los métodos apropiados. Las clases que usan delegados envían mensajes a sus delegados en eventos contratados. La API define la API entre clase y delegado y es diferente para cada clase que usa el patrón, pero la API generalmente consiste en mensajes que le preguntan al delegado cómo manejar un evento en particular. Una ventaja del patrón delegado sobre la subclasificación es que una clase puede implementar múltiples protocolos delegados, lo que permite que sus instancias actúen como delegados para múltiples clases. De manera similar, una instancia de objeto puede ser el delegado para otros muchos objetos (por lo tanto, la mayoría de las API delegadas pasan el objeto como primer argumento a cada mensaje en la API). El patrón de delegado no es tan común en otros marcos de interfaz de usuario (aunque Qt utiliza el patrón de delegado en su marco de Modelo / Vista), y no es lo mismo que los delegados .Net / CLR que son punteros de función esencialmente tipados.

El patrón de fuente de datos a menudo es utilizado por las NSView en Cocoa que tienen datos de estado complejos como NSBrowser, NSTableView, NSOutlineView, etc. El protocolo fuente de datos define una API que las instancias de estas (y otras) clases pueden usar para obtener el datos para mostrar en la vista. Aunque las NSController y Cocoa Bindings han reemplazado a muchos usos del patrón de fuente de datos, todavía es común y muy poderoso. Al igual que el patrón delegado descrito anteriormente, parte de su poder proviene de un objeto que puede actuar como fuente de datos para múltiples instancias que utilizan fuentes de datos (y posiblemente incluso instancias de múltiples clases que tienen diferentes protocolos de origen de datos). El patrón de fuente de datos se usa comúnmente en otros marcos de interfaz de usuario, como Qt (en el marco Modelo / Vista donde el modelo es análogo a la fuente de datos) y WPF / Silverlight (donde la fuente de datos podría ser más análoga al modelo de vista) )


Para hacerlo breve:

El delegado se relaciona con la UI y las acciones del usuario contra las celdas y la tabla.

métodos comunes: willSelectRow, didSelectRow, willDisplay, heightForRow, willBeginEditingAt

El origen de datos trata sobre la edición, la población y la visualización de datos en la tabla vista.

métodos comunes canEditRowAt, commit, titleForHeaderInSection, cellForRowAt, numberOfSections, sectionIndexTitles