2017-06-12 79 views
0

我一直在尝试做一些代码,允许用户“附加”到特定单元格的特定模型。我打算通过协议和associatedType方法来做到这一点。如何在Swift中测试与associatedType协议的一致性?

这里的计划:

细胞符合MTZSectionRowConfigurable时,他们可以显示数据,但他们不一定需要:

public protocol MTZSectionRowConfigurable { 
    associatedtype T: MTZSectionRowModel 
    func configure(with model: T?) 
} 

通过使用typealias,它们允许用户定义哪种模式他们“再要代表:

class SignOutCell: UITableViewCell, MTZSectionRowConfigurable { 
    typealias T = SignOutModel 
    var redLabel: UILabel! 
    // ... 
    func configure(with model: SignOutCellModel?) { 
     self.redLabel.text = model?.text 
    } 
} 

模型只是顺应MTZSectionRowModel明确声明补偿atibility。

但是,由于表示模型是可选的,我需要在调用configure方法之前检查单元以支持它们。这是对cellForRowAtIndexPath:

if let cell = cell as? MTZSectionRowConfigurable { 
    cell.configure(with: sectionRow.model) 
} 

完成。在上述例子中,是sectionRow.modelMTZSectionRowModel?类型。

以上代码不能编译。它产生臭名昭著:

“协议‘MTZSectionRowConfigurable’只能作为一种通用的约束,因为它具有自我或相关类型的要求”

我试图检查电池也回应#selector,但不幸的是,同样的错误适用。

有什么办法可以使这段代码有效吗?我错过了什么吗?我可以放弃associatedType,在每个单元格上实施广泛的方法MTZSectionRowModel,但是然后我需要在每个实现内部施放,但在我看来这不是最佳解决方案。

回答

0

我明白你正在尝试做什么,我自己也做过。然而,这比现在所做的要多一点。你在Andy Matuschak的gist中找到答案。

为了与SO答案的最佳实践保持一致,我将解释其原因。让我们从最后开始。 cellForRow...这是objc func,它需要返回UITableViewCell?。所以我们已经知道,在某些时候我们会丢失类型信息(例如,你的SignOutCell类不是返回的,它是它的超类,UITableViewCell)。鉴于我们最终得到了UITableViewCell,我们如何才能做到您想做的事情并生成SignOutCell并对其进行配置?答案在于定义安迪在他的要点(在此链接)中描述的CellFactory中的完成处理程序。然后他使用bridgedDataSource将一种细胞类型转换为另一种细胞类型。我定制了他的代码,以允许根据输入参数返回4种不同类型的单元格。例如,我的UITableViewController可能包含4个UITableViewCell项目,每个项目的布局和数据模型都可能非常不同。我会参数CellFactory接受enum CellType,我预先定义了4种类型。然后,在细胞工厂内,我使用switch cellType来设置细胞(此时我有细胞和模型数据的所有类型信息)。最后,bridgedDataSource返回良性UITableViewCell这使UIKit非常高兴,它具有我需要的所有品质。 Andy所依赖的基本概念之一是分解。我相信他在某处有一个YouTube视频,或者在他的网站上有一段视频,他可以在这里看到。我会看看如果我能找到它并更新答案。