如何在 VIPER 中为演示者 UITableViewCell 委托创建模板协议

问题描述

我在 Swift 中使用 VIPER 架构。
我想使用演示者的协议来获取 UITableView 委托,因为我不想为所有演示者重复这些方法的声明。

所以我创建了协议

protocol TableViewPresenterProtocol: class {
    associatedtype Data
    func numberOfSections()-> Int
    func haeaderTitle(secton: Int)-> String?
    func numberOfRows(section: Int)-> Int
    func itemForCell(at indexPath: IndexPath)-> Data
    func didSelect(at indexPath: IndexPath)
}

//for make optional
extension TableViewPresenterProtocol {
    func numberOfSections()-> Int {
        return 1
    }
    
    func haeaderTitle(secton: Int)-> String? {
        return nil
    }
}

class PaymentViewController {
    var presenter: (PaymentPresenterProtocol & TableViewPresenterProtocol)?
}

但 XCode 显示错误

Protocol 'TableViewPresenterProtocol' 只能用作通用约束,因为它具有 Self 或关联类型要求

我应该在源代码中的哪个位置解决这个问题?

解决方法

在您的 PaymentViewController 中,当前编译器没有机会识别您的 associatedtype Data 所指的内容。它可以是 String,也可以是 Int 或其他任何东西。斯威夫特不喜欢那样。它不能使用它,因为 associatedtype 真正指的是什么是不明确的。

为了解决这个问题,我们可以使用 TableViewPresenterProtocol 作为通用约束来告诉 Swift 我们实际上指的是什么类型。在您的情况下,它看起来像这样:

class PaymentViewController<A: TableViewPresenterProtocol> {
    var presenter: (A)?
}

假设您创建了一个符合 TableViewPresenterProtocol 的类:

class SomeOtherController: TableViewPresenterProtocol {
     typealias Data = String
     // Other conformance stuff here
}

现在你可以说:

PaymentViewController<SomeOtherController>()

Swift 很清楚演示者的 associatedtype DataString