数据源和委托之间有什么区别?

Jes*_*and 41 cocoa delegates datasource protocols

我有一个与Cocoa框架设计模式相关的基本问题.

委托和数据源之间有什么区别?

它们都可以使用@protocols声明,但是一些类或框架正在使用delegate,而另一些正在使用datasource.

我可以理解的UI/NSTableViewdelegate对UI相关事件的响应,而datasource与数据完全相关.但是,我不知道Cocoa的UI类之外的任何数据源实现.

注意:

  • 我在这个问题中提到的代表并不总是与UI事件有关.
  • 数据源问题已得到解答.

kub*_*ubi 46

数据源提供数据,委托提供行为.

MVC中,数据源位于模型层中,委托位于控制层中.

实际上,在第二个想法中,数据源通常是较低的控制器,更接近模型.我不认为我曾经使用过模型对象作为我的数据源.


Bar*_*ark 34

委托和数据源模式在很大程度上是独立的,并且是正交的:

委托模式在Cocoa中非常常见,并且允许委托(在OS X 10.6之前实现非正式委托协议的任何实例,或@protocol在10.6及更高版本中实现正式委托)来修改对象实例的行为.通常使用此模式而不是子类化:您可以提供响应适当方法的委托,而不是对类进行子类化以更改其行为.使用委托的类在签约事件中向其委托发送消息.类和委托之间的API由类定义,并且对于使用该模式的每个类是不同的,但API通常由询问委托如何处理特定事件的消息组成.委托模式优于子类化的一个优点是类可以实现多个委托协议,允许其实例充当多个类的委托.类似地,对象实例可以是多个其他对象的委托(因此大多数委托API将对象作为API中每个消息的第一个参数传递).委托模式是不是在其他的UI框架作为通用(虽然Qt的不使用它的模型/视图框架的委托模式),并且是一样的,其本质上类型的函数指针的.Net/CLR的代表.

数据源模式通常由NSViewCocoa中具有复杂状态数据的子类使用,例如NSBrowser,NSTableView,NSOutlineView等.数据源协议定义了一个API,这些(和其他)类的实例可用于获取数据在视图中显示.虽然NSController和Cocoa Bindings架构已经取代了数据源模式的许多用途,但它仍然很常见且非常强大.与上面描述的委托模式一样,它的一部分功能来自一个对象,它可以作为多个数据源使用实例的数据源(甚至可能是具有不同数据源协议的多个类的实例).数据源模式通常用于其他UI框架,例如Qt(在Model/View框架中,模型类似于数据源)和WPF/Silverlight(其中数据源可能更类似于视图模型) ).

  • @Jesse为了清楚起见,委托和数据源都没有直接响应UI事件(即通过运行循环传递给应用程序的`NSEvent`).对象可以询问委托如何响应事件(NSEvent`类型事件或来自其他对象的任何其他消息).数据源不在UI类之外使用,因为它们不是必需的; MVC的模型是它自己的数据源. (2认同)

Hon*_*ney 12

在回答问题之前,你必须更好地理解代表团的设计模式:让我先从一个问题开始:

默认情况下,TableView是这样的:

在此输入图像描述

UITableView如何知道要呈现多少个单元?在每个细胞中呈现什么?

  • 它本身并不知道.
  • 它要求另一个类通知它关于细胞的数量和返回的细胞(细胞图像,细胞标签,细胞标签等)对自身的值.您通常会在ViewController(委托类)中看到tableView(委托类)
  • 这个一个类的概念要求另一个被称为委托!

既然您知道代表团是什么,那么回答OP的实际问题:

这主要是语义差异的巨大问题.
如果您只是使用(而不是创建自己的协议)基金会的代表和数据源,那么它对您来说无关紧要.但是,如果您打算编写自定义协议,那么理解它们将有助于您更好地编写(并具有更高重要性的读取,折射器)代码.

从一个开发者的角度,他们都处理了delegat-之间的互动ING类和委托类.

数据源

数据源几乎与委托相同.不同之处在于与委托对象的关系.数据源不是委托控制用户界面,而是委托数据控制.委托对象(通常是视图对象,例如表视图)保存对其数据源的引用,并偶尔询问它应显示的数据.数据源(如委托)必须采用协议并至少实现该协议所需的方法.数据源负责管理它们为委托视图提供的模型对象的内存.

在Layman的术语中:

数据源的交易大多是什么,通常它的东西在初始化时.大多与委托交易如何饲料你一些参数给予一定的行为,即如果用户点击这个......应该发生什么?如果他们刷了......会发生什么?

作为tableView的示例:

DataSource
里面有什么?我呈现什么样的细胞? 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  
Run Code Online (Sandbox Code Playgroud)

代表方法

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)
Run Code Online (Sandbox Code Playgroud)

我显然选择性地选择了一些数据源方法不返回,并且一些委托方法确实返回


代表
在完成页脚显示后,我应该做什么/什么'行为形式',你想让我发出警报吗?didEndDisplayingFooterView

我是否会使用accessoryType为细胞提供一些额外的功能? accessoryTypeForRowWithIndexPath


luk*_*ing 7

从我的角度来看,a DataSource是一个不知道数据在哪里的对象,因此你应该提供它.比如告诉对象列中有多少项.

A Delegate,它是对象向您显示的一部分,必须由您的类实现,因为该对象知道数据的位置,但它不知道如何正确使用它.


Mod*_*era 5

简而言之:

委托与 UI 和用户对单元格和表格的操作有关。

常用方法:willSelectRow、didSelectRow、willDisplay、heightForRow、willBeginEditingAt

数据源处理 tableview 上数据的编辑、填充和显示。

常用方法 canEditRowAt、commit、titleForHeaderInSection、cellForRowAt、numberOfSections、sectionIndexTitles