数据源类似于委托,只不过它的方法提供了供其他对象显示的数据。Cocoa中带有数据源的类主要有UITableView、UICollectionView、UIPickerView与UIPageView-Controller。对于每个类来说,数据源必须要正式使用数据源协议并实现必需的方法。
有些初学者对于数据源的必要性感到惊奇。为何表数据不是表的一部分?为何要有一些包含着数据的固定的数据结构?原因在于这种架构违背了一般性。使用数据源可以将显示数据的对象与管理数据的对象分离开来,后者可以自由存储和获取所需的数据(参见第13章的模型—视图—控制器)。唯一的要求就是数据源必须能快速提供信息,因为当需要显示数据时会实时地向数据源请求数据。
另一个惊奇之处在于数据源不同于委托。但这又回到一般性问题了;这是一个选项而不是必需的。并没有什么理由限制数据源与委托不能成为同一个对象,大多数时候它们可能都是一样的。实际上,在大多数情况下,数据源方法与委托方法可以密切配合;你可能都意识不到这种差别。
下面这个示例来自于我编写的应用,它实现了UIPickerView,让用户可以根据自己输入的阶段数(“1阶段”“2阶段”等)来配置游戏。前两个是UIPickerView数据源方法;第3个是UIPickerView委托方法。它通过这3个方法向选择器视图提供内容。
extension NewGameController: UIPickerViewDelegate, UIPickerViewDataSource { func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { return 1 } func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return 9 } func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return "/(row+1) Stage" + ( row > 0 ? "s" : "") }}