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

Cai*_*son 4 protocols ios cocoapods swift

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

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

模块 1 中

public protocol ActionableCell {
    func performAction()
}
Run Code Online (Sandbox Code Playgroud)

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

因此,在 tableview 的类(模块 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()
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,有时单元格是在模块 1 中声明的,但是如果没有更进一步的模块,操作是不可能的,所以在模块 1 中我声明了类:

open class SomeCell: UITableViewCell {
}
Run Code Online (Sandbox Code Playgroud)

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

extension SomeCell: ActionableCell {
    func performAction() {
        // Do Stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,只是为了澄清:

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

然后在第二个模块中: SomeCell扩展为符合ActionableCell

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

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

Cai*_*son 5

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

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

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