0

在我的应用程序中,每当某个控制器中有 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 协议扩展中?

4

1 回答 1

2

您可以通过协议扩展来实现您正在寻找的东西。仅当实现协议的对象实际上是 UIViewController 时,扩展才会适用。

protocol something {
    func method()
}
extension something where Self: UIViewController {
    func method() {
        //Default implementation
    }
}
于 2017-01-16T14:13:48.800 回答