What's the difference between data source and delegate?
I have a fundamental question related to Cocoa frameworks design patterns.
What's the difference开发者_运维知识库 between delegate and data source?
Both of them could use @protocols
declaration, but some classes or frameworks are using delegate
, and some others are using datasource
.
All I can understand from UI/NSTableView
is the delegate
respond to UI-related events, while the datasource
is purely related to the data. But, I don't know any data source implementations outside the UI classes of Cocoa.
Note:
- The delegate I mentioned in this question is not always related to UI events.
- The data source question has been answered.
The datasource supplies the data, the delegate supplies the behavior.
In MVC, datasource is in the model layer and the delegate is in the control layer.
Actually, on second thought, the datasource is usually controller that is lower down, closer to the model. I don't think I've ever used a model object as my datasource.
The delegate and datasource patterns are largely independent, and orthogonal:
The delegate pattern is very common in Cocoa and allows a delegate (any instance implementing the informal delegate protocol prior to OS X 10.6, or the formal delegate @protocol
in 10.6 and later) to modify the behavior of an object instance. This pattern is often used instead of subclassing: instead of subclassing a class to change its behavior, you supply a delegate that responds to the appropriate methods. Classes that use delegates send messages to their delegate at contracted events. The API between class and delegate is defined by the class and is different for each class that uses the pattern, but the API generally consists of messages asking the delegate how to handle a particular event. One advantage of the delegate pattern over subclassing is that a class may implement multiple delegate protocols, allowing its instances to act as delegate for multiple classes. Similarly, an object instance can be the delegate for multiple other objects (hence most delegate APIs pass the object as the first argument to each message in the API). The delegate pattern is not as common in other UI frameworks (though Qt does use the delegate pattern in its Model/View framework), and is not the same as .Net/CLR delegates which are essentially typed function pointers.
The data source pattern is often used by NSView
sub-classes in Cocoa that have complex state data such as NSBrowser, NSTableView, NSOutlineView, etc. The data source protocol defines an API that instances of these (and other) classes may use to get the data to display in the view. Although the NSController
and Cocoa Bindings architectures have replaced many uses of the data source pattern, it's still common and very powerful. Like the delegate pattern described above, part of its power comes from an object being able to act as the data source for multiple data-source-using instances (and possibly even instances of multiple classes that have different data source protocols). The data source pattern is used commonly in other UI frameworks, such as Qt (in the Model/View framework where the model is analogous to the data source) and WPF/Silverlight (where the data source might be more closely analogous to the view model).
Suppose you had 3 tableviews. For dogs, cats and birds. Tapping on each cell would show a new screen with the enlarged photo of it.
To design this, you'll need to come up with 3 separate datasources for dogs, cats and birds. You basically need three arrays.
However you don't need 3 tableview delegates. Because the behavior of the tableviews are all the same. They all just take present a viewController and fill it with a UIImage. This is only true if you delegate is written in a generic way i.e. there's no dog, cat or bird specific code in the delegate.
Having that said you could abstract out the dog, cat, bird from the data source, but my answer was just a contrived example. Some custom objects are too complex to use the same structure, hence the need to have 3 datasources.
Old answer:
Before answering the question, you must better understand the delegation design pattern: Let me begin with a question:
By default a TableView is like this:
How does a UITableView know how many cells to present? what to present in each cell?
- By itself, it doesn't know.
- It asks another class to inform it about the number of cells and what cell to return ( what cellimage, celltitle, cellsubtitle,etc.) values to itself. You usually see a tableView (delegating class) inside a ViewController (delegate class)
- This concept of one class asking another is known as delegation!
Now that you know what Delegation is, to answer the actual question of the OP:
It's mostly a HUGE matter of semantic differences.
If you are only to use ( not to create your own protocol) foundation's delegates and datasources then it really doesn't matter for you. However if you intend to write custom protocols then understanding them would help you to write ( and with a higher importance read, refractor) code better.
From a developer's point of view, They both deal with the interaction between the delegat-ing class and delegate class.
Data Source
A data source is almost identical to a delegate. The difference is in the relationship with the delegating object. Instead of being delegated control of the user interface, a data source is delegated control of data. The delegating object, typically a view object such as a table view, holds a reference to its data source and occasionally asks it for the data it should display. A data source, like a delegate, must adopt a protocol and implement at minimum the required methods of that protocol. Data sources are responsible for managing the memory of the model objects they give to the delegating view.
In Layman's terms:
DataSource deals mostly with what and usually does it's stuff upon initialization. Delegate deals mostly with how and feeds you some parameters to give a certain behavior ie if the user clicked this... what should happen? if they swiped...what should happen?
As an example for tableView:
DataSource
What does it have inside of it? What kind of cell am I presenting? cellForRowAtIndexPath
.
What is the title of Section? titleForHeaderInSection
How many cells are they? numberOfRowsInSection
And therefore you usually return values. For delegates it's more common to be of type void
.
Datasource methods
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
Delegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath)
func tableView(tableView: UITableView, didEndEditingRowAtIndexPath indexPath: NSIndexPath)
I obviously chose selectively as some datasource methods don't return and some delegate method do return
Delegate
What should I do/what 'form of behavior' should I use after finishing the display of the footer, do you want me to pop an alert?didEndDisplayingFooterView
Am I going to have accessoryType that gives the cell some extra features? accessoryTypeForRowWithIndexPath
From my point of view, a DataSource
is an object that doesn't know where the data is, and thus you should provide it. Such as telling an object how many items in a column.
A Delegate
, which is a part that object shows to you, must be implemented by your class, because the object knows where the data is, but it does not know how to use it correctly.
To make it short:
Delegate relates to the UI and User actions against the cells and table.
common methods: willSelectRow, didSelectRow, willDisplay, heightForRow, willBeginEditingAt
Data Source deals with the editing, population and displaying of data on the tableview.
common methods canEditRowAt, commit, titleForHeaderInSection, cellForRowAt, numberOfSections, sectionIndexTitles
Both are Protocol, now the main intension of Protocol is to keep an universal coding practice, or same coding practice for all(to my understanding). Suppose I am creating a tableView without a UITableViewDataSource & UITableViewDelegate, I would create the tableView such a way that you woud not. Thats where Protocol comes, apple created some set of rule or protocol and everybody have to follow that. Now DataSource & Delegate are obviously Protocol, seeing the name you could understand DataSource deals with something like numberOfRowsInSection, cellForRowAtIndexPath, numberOfSections of tableView where some kind of data is being taken/processed, and Delegates are didSelectRow, willSelectRow, heightForRow etc of tableView where its related with some kind of UI change/action. So its just naming convention nothing hypothetical to keep the task separate. As @kubi said earlier: The datasource supplies the data, the delegate supplies the behaviour.
精彩评论