数据源和委托有什么区别?
我有一个与Cocoa框架devise模式有关的基本问题。
委托和数据源有什么区别?
他们两个都可以使用@protocols
声明,但是一些类或框架正在使用delegate
,还有一些正在使用datasource
。
从UI/NSTableView
我可以理解的是delegate
响应UI相关的事件,而datasource
纯粹与数据相关。 但是,我不知道Cocoa UI类以外的任何数据源实现。
注意:
- 我在这个问题中提到的代表并不总是与UI事件有关。
- 数据源问题已被回答。
代表和数据源模式在很大程度上是独立的,并且是正交的:
委托模式在Cocoa中非常普遍,允许委托(在OS X 10.6之前实现非正式委托协议的任何实例,或者在10.6及更高版本中正式委托@protocol
)来修改对象实例的行为。 这种模式通常用来代替子类化:而不是通过子类来改变它的行为,而是提供一个委托来响应相应的方法。 使用委托的类在合同事件中将消息发送给其委托。 类和委托之间的API由类定义,对于使用该模式的每个类都是不同的,但是API通常由询问委托如何处理特定事件的消息组成。 委托模式优于子类的一个优点是一个类可以实现多个委托协议,允许其实例充当多个类的委托。 同样,对象实例可以是多个其他对象的委托(因此大多数委托API将对象作为API中每个消息的第一个parameter passing)。 委托模式在其他UI框架中并不常见(尽pipeQt在其Model / View框架中使用了委托模式), 并不像.NET / CLR代表那样,它们本质上是types化的函数指针。
数据源模式经常被Cocoa中的NSView
子类使用,它们具有复杂的状态数据,例如NSBrowser,NSTableView,NSOutlineView等。数据源协议定义了一个API,这些(和其他)类的实例可以用来获取要在视图中显示的数据。 尽pipeNSController
和Cocoa Bindings体系结构已经取代了数据源模式的许多用途,但它仍然很常见,而且非常强大。 像上面介绍的委托模式一样,它的部分function来自一个对象,它可以作为多个使用数据源的实例(甚至可能有多个具有不同数据源协议的类的实例)的数据源。 数据源模式通常在其他UI框架中使用,例如Qt(在Model / View框架中模型与数据源类似)和WPF / Silverlight(其中数据源可能更接近于视图模型)。
数据源提供数据,委托供应行为。
在MVC中 ,数据源在模型层,委托在控制层。
实际上,第二个想法是,数据源通常是较低的控制器,更接近模型。 我不认为我曾经使用模型对象作为我的数据源。
从我的angular度来看, DataSource
是一个不知道数据在哪里的对象,因此应该提供它。 如告诉一个对象一列中有多less项。
Delegate
是对象向你显示的一部分,必须由你的类来实现,因为对象知道数据在哪里,但不知道如何正确使用它。
在回答问题之前,您必须更好地了解委托devise模式:让我从一个问题开始:
默认情况下,一个TableView是这样的:
UITableView如何知道要呈现多less个单元格? 什么在每个细胞中呈现?
- 它本身并不知道。
- 它要求另一个class级向其通报有关细胞数量和细胞回报(细胞图像,细胞标记,细胞标记等)的值。 你通常在ViewController(委托类)中看到一个tableView(委托类)
- 代表另一个class级的这个概念被称为代表团!
现在您已经知道授权是什么了,回答OP的实际问题:
这主要是一个语义差异的巨大问题。
如果你只是使用(而不是创build自己的协议)基金会的代表和数据源,那么这对你来说并不重要。 但是,如果您打算编写自定义协议,那么了解它们将有助于您更好地编写代码(并且具有更高的重要性读取,折射)代码。
从开发者的angular度来看,他们都处理委托类和委托类之间的交互。
数据源
数据源与代表几乎完全相同。 区别在于与委托对象的关系。 数据源不是委托控制用户界面,而是委托数据控制。 委托对象(通常是诸如表格视图之类的视图对象)持有对其数据源的引用,并偶尔会要求其显示数据。 数据源就像一个代表一样,必须采用一个协议,并至less实现该协议所需的方法。 数据源负责pipe理他们赋予委托视图的模型对象的内存。
按照莱曼的说法:
DataSource主要处理什么 ,通常是初始化时的东西。 委托主要处理如何和给你一些参数给予某种行为,即如果用户点击这个…应该发生什么? 如果他们刷了…会发生什么?
作为tableView的一个例子:
数据源
它里面有什么? 我提出什么样的细胞? cellForRowAtIndexPath
。
Section的标题是什么? titleForHeaderInSection
它们有多less个单元格? numberOfRowsInSection
因此,你通常返回值。 对于代表来说,更常见的是void
types。
数据源方法
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)
我明显地select了一些数据源方法不返回和一些委托方法返回
代表
我应该做什么/在完成页脚的显示之后,我应该使用什么样的“行为forms”,你想让我popup一个改动吗? didEndDisplayingFooterView
我将有accessoryType给单元格一些额外的function? accessoryTypeForRowWithIndexPath