通过框架之间的扩展实现 Swift 协议一致性

Posted

技术标签:

【中文标题】通过框架之间的扩展实现 Swift 协议一致性【英文标题】:Swift protocol conformance by extension between frameworks 【发布时间】:2018-02-13 09:04:44 【问题描述】:

出于各种原因,我将 Swift ios 应用程序的代码库拆分为一系列模块,主要以相当线性的方式依赖。这个问题的基础是:如果我在一个模块中有一个类,然后扩展它以符合另一个模块中的协议,那么该类型的所有对象都会自动符合吗?。我们暂时称它们为 Module 1Module 2

这种模块化的结果是,并非给定 UITableView 类的每个单元格都将在同一模块中声明。因此,为了允许我使用该模块之外的单元,我声明了一系列描述单元基本功能的协议。例如:

模块1中:

public protocol ActionableCell 
    func performAction()

tableview 使用它,所以每次选择一个单元格时,如果它符合 ActionableCell 则在其上调用 performAction()。这允许 tableview 处理它不知道的单元格上的点击。

所以,在 tableview 的类中(Module 1):

open class SomeTableView: UITableView 
    // Blah

        open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    // If the cell is actionable, inform it that it has been selected
    if let cell = tableView.cellForRow(at: indexPath) as? ActionableCell 
        cell.performAction()
    

但是,有时单元格是在 Module 1 中声明的,但是如果没有更进一步的模块,则该操作是不可能的,因此在 Module 1 中声明了该类:

open class SomeCell: UITableViewCell 

然后在 模块 2 中,我使该单元格符合 ActionableCell

extension SomeCell: ActionableCell 
    func performAction() 
        // Do Stuff
    

所以,澄清一下:

在第一个模块中: 声明了ActionableCell,声明了SomeTableView,声明了SomeCell,但符合ActionableCell

那么在第二个模块中:SomeCell被扩展为符合ActionableCell

如果我的项目中包含并构建了这两个模块,但 Module 2 没有直接导入到 Swift 文件中的 tableview 类中(执行转换为 ActionableCell 的地方),或者在哪里创建单元格,单元格是否符合ActionableCell,因为扩展是项目的一部分?如果不是,那么在什么时候导入扩展很重要?

我知道不导入第二个模块就无法访问SomeCell的扩展属性,但这是关于是否可以在不导入扩展的情况下进行转换。

【问题讨论】:

【参考方案1】:

我意识到这没有收到任何答案,我已经使用这种方法有一段时间了,所以我想我应该发布一个答案。

事实证明,类扩展是全局性的——如果一个模块扩展了一个类,则由于该模块的存在,它会为每个模块扩展。这与是否导入第二个模块无关,仅在安装时。

所以,例如如果 Module A 包含类 Foo,并且 Module B 扩展 Foo 以符合某些协议(例如 Hashable)。如果Module A 然后检查Hashable 的一致性,它会发现Foo 确实符合当且仅当Module B 也存在。

【讨论】:

以上是关于通过框架之间的扩展实现 Swift 协议一致性的主要内容,如果未能解决你的问题,请参考以下文章

Swift21-协议

Objective-C 类型的 Swift 2 协议扩展和一致性

通过扩展自动合成 Swift 结构或枚举的 Equatable 一致性

swift 学习- 25 -- 协议 02

Swift下面字典(json)和模型的转换

OpenTok/TokBox 的 Swift 协议一致性错误