Throughout the iOS SDK and the Foundation framework, a design pattern named the delegation pattern is used. The delegation pattern enables one object to perform actions on behalf of another object. When implemented correctly, this patterns allows you to separate the concerns between different objects and decouple them. The following figure shows how the delegation pattern for a UITableView component and its UITableViewDataSource works:
The UITableView makes use of two delegates in order to render a list. One is called the delegate, the other is called the data source. Whenever you use a UITableView, you must explicitly configure the data source and delegate properties. At runtime, the UITableView will call methods on its delegate and data source in order to obtain information about cells, handle interactions, and more.
If you look at the documentation for the UITableView's delegate property you'll find out that its type is UITableViewDelegate?. There are two things that we learn from this type. First, it tells you that any object that wants to act as the UITableView's delegate must conform to the UITableViewDelegate protocol. Second, the question mark tells you that the delegate is an Optional property. The question mark after the type is what gives this away. An Optional property can either have a value of the specified type (UITableViewDelegate in this case) or nil. The UITableView's delegate must be Optional because it's not strictly required to set it; you can create an instance of UITableView without ever setting the delegate property.
A protocol, like UITableViewDelegate, provides a set of properties and/or methods that any object that conforms to (or adopts) this protocol must implement. In some cases all of these properties and methods are required; the compiler will throw an error if a method specified by the protocol is not implemented. In other cases, there might be methods that are optional; you don't have to implement these in order to conform to the protocol. An example of a protocol with optional methods is UITableViewDelegate. You can conform to this protocol without implementing any extra methods.
When implementing a UITableView's data source, you'll find that the UITableViewDataSource protocol has a couple of mandatory methods to ensure that a data source is able to provide UITableView with the minimum amount of information needed in order to render the cells you want to display.
If you've never heard of delegation and protocols before, you might feel like this is all a bit foreign and complex. That's OK; throughout this book you'll gain a deeper understanding of protocols and how they work. You'll even learn a thing or two about a special programming paradigm called protocol-oriented programming. For now, it's important to be aware that a UITableView always asks another object for data through the UITableViewDataSource protocol and that interactions are handled though the UITableViewDelegate.
When you take a closer look at UITableView and the steps involved in displaying a list of contents you'd find the following steps:
- UITableView needs to reload the data.
- UITableView checks whether it has a dataSource and asks it for the number of sections in the list.
- Once the dataSource responds with the number of sections, the table view will figure out how many cells are required for each section. This is done by asking the dataSource for the number of cells in each section.
- Now that the cell knows the amount of content it needs to render, it will ask its dataSource for the cells that it should display.
- Once the dataSource provides the required cells based on the number of contacts, the UITableView will request that it displays the cells one by one.
This process is a good example of how UITableView uses other objects to provide data on its behalf. Now that you have a good understanding of how delegation works for UITableView, it's about time you start implementing this in your own app.