在我的应用程序中,每当某个控制器中有 UITableView 时,我都必须编写大量样板代码。为了消除它,我创建了一个BaseTableViewController来实现一些重复使用的UITableDataSource
操作,例如tableView(_:numberOfRowsInSection:)
和tableView(_:cellForRowAt:)
。在tableView(_:numberOfRowsInSection:)
中,我的 BaseTableViewController 从另一个方法(我们称之为它rowCount(inSection:)
)检索一个部分中的实际行数并使用它执行一些计算,然后将结果返回给委托调用者。每个继承 BaseTableViewController 的类都必须覆盖该rowCount(inSection:)
方法并在给定部分中返回其正确的行数(BaseTableViewController 本身在其默认实现中返回 0)。
现在,我的一些表视图控制器支持显示记录的分页 - 当用户将表视图滚动到最后一行时,将从网络中检索下一批行。为了让事情更加面向协议,我为可分页控制器创建了一个协议:
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
,它们共享它的默认实现,该实现(可能)放置在 Pageable 协议扩展中?