在我的应用程序中,我有很多样板代码,只要在某个控制器中存在UITableView,就必须写入代码。为了消除它,我创建了一个BaseTableViewController,它实现了一些重复使用的UITableDataSource
操作,如tableView(_:numberOfRowsInSection:)
和tableView(_:cellForRowAt:)
。在tableView(_:numberOfRowsInSection:)
中,我的BaseTableViewController从另一个方法(我们称之为rowCount(inSection:)
)中检索一个节中的实际行数,并使用它执行一些计算,然后将结果返回给委托调用者。子类BaseTableViewController的每个类都必须覆盖rowCount(inSection:)
方法,并在给定部分返回适当的行数(BaseTableViewController本身在默认实现中返回0)。为被覆盖的UIViewController方法提供一个默认的实现,但只有当控制器符合协议时
现在,我的一些表格视图控制器支持显示记录的分页 - 当用户将表格视图滚动到最后一行时,从网络中检索下一批行。试图让事情变得更加协议为本,我创建了分页控制器的协议:
protocol Pageable: class {
associatedtype DataType
var pages: [[DataType]] { get set } // Each page is an array of elements, hence the table in a table
func loadNextPage()
}
如果控制器为Pageable
,在rowCount(inSection:)
方法总是看起来是这样的:
override func rowCount(inSection: Int) -> Int {
return self.pages[section].count
}
这是乏味的,因为每个也是Pageable的BaseTableViewController后代都必须具有此确切的实现,这违反了DRY。
我不能在Pageable
的协议扩展中添加默认实现,因为控制器已经有自己的实现继承自BaseTableViewController。我可以创建一个PageableTableViewController(BaseTableViewController的子类),它提供自己的覆盖实现rowCount(inSection:)
,但这不是非常面向协议的。我也尝试将rowCount(inSection:)
方法移动到一个协议上,但是如果我使BaseTableViewController的所有后代与协议扩展一致,则扩展Pageable
来实现该方法将不起作用。
我将如何建立一个机制,其中的BaseTableViewController
所有子类将能够覆盖rowCount(inSection:)
方法,但是当他们Pageable
,他们分享这是一个默认实现的(可能)放置在一个可分页协议扩展?