通过框架之间的扩展实现 Swift 协议一致性
Posted
技术标签:
【中文标题】通过框架之间的扩展实现 Swift 协议一致性【英文标题】:Swift protocol conformance by extension between frameworks 【发布时间】:2018-02-13 09:04:44 【问题描述】:出于各种原因,我将 Swift ios 应用程序的代码库拆分为一系列模块,主要以相当线性的方式依赖。这个问题的基础是:如果我在一个模块中有一个类,然后扩展它以符合另一个模块中的协议,那么该类型的所有对象都会自动符合吗?。我们暂时称它们为 Module 1 和 Module 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 协议一致性的主要内容,如果未能解决你的问题,请参考以下文章
Objective-C 类型的 Swift 2 协议扩展和一致性