2017-01-16 44 views
0

在我的应用程序中,我有很多样板代码,只要在某个控制器中存在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,他们分享这是一个默认实现的(可能)放置在一个可分页协议扩展?

回答

2

您可以使用协议扩展实现您正在寻找的内容。该扩展将适用于防止实现协议的对象实际上是UIViewController。

protocol something { 
    func method() 
} 
extension something where Self: UIViewController { 
    func method() { 
     //Default implementation 
    } 
} 
相关问题