ios - Swift 中的协议(protocol)扩展与类扩展

标签 ios swift protocols

假设有一个协议(protocol)Draggable,通常会被一个UIView对象符合

protocol Draggable {
  drag()
}

我们可以在协议(protocol)扩展中实现 drag() 作为选项 1

// option 1
extension Draggable where Self: UIView {
  func drag() {
    // implementation
  }
}
extension UIView: Draggable {} // added after @Rich Tolley's answer

或者我们可以在 UIView 扩展中实现 drag() 作为选项 2

// option 2
extension UIView: Draggable {
  func drag() {
    // implementation
  }
}

这是我的问题:

  • 这两种方法(选项 1 和选项 2)之间有区别吗?
  • 如果是,有什么区别以及我们在设计项目或库时如何选择?

想法会有帮助。

最佳答案

是的,有区别:(编辑:或者至少在这个 q 的原始版本中没有添加 extension UIView : Draggable {} 到选项 1 的末尾).

  • 选项 1 为符合 DraggableUIView 实例创建默认实现。您仍然需要在声明中标记您希望符合 DraggableUIView:class MyView : Draggable。任何符合 Draggable 但不是 UIView 子类的东西都需要提供自己的实现。

  • 选项 2 扩展所有 UIView,使它们符合Draggable。除非还为这些类编写了单独的扩展,或者它们手动符合协议(protocol),否则没有其他任何东西可以是 Draggable。无需在类声明中添加Draggable

协议(protocol)扩展通常是更好的选择。在这种情况下,这显然是正确的,因为并非所有 UIView 都可以是 Draggable。此外,沿协议(protocol)扩展路线进行下去意味着您可以创建一个不是 UIView 子类的 Draggable 对象,如果有必要(不可否认,这不太可能,因为大多数 Cocoa 控件都是 UIView 子类 - 虽然不是所有 -UIBarButtonItem 不是,很奇怪)

如果您遵循选项 2,在很多情况下您将向 UIView 添加不必要的方法,这违反了良好的面向对象设计 - 特别是接口(interface)隔离原则(客户端不应该被迫依赖他们不使用的方法 ) - 这是 SOLID principles 中的“我”

关于ios - Swift 中的协议(protocol)扩展与类扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35534651/

相关文章:

ios - 改变非交错浮点的间距

ios - 应用商店收据

ios - 将 Node 放置在 ARKit World 中的触摸位置

swift - 将有关录制麦克风信号的旧 Swift 代码行翻译为 Swift 4.2

swift - 有没有办法在函数指针中设置协议(protocol)的数据类型?

Swift 继承协议(protocol)和父协议(protocol)的一致性检查

ios - UIScrollView 最大和最小 contentOffsets?

ios - Xcode 5 中带有工作区的静态库

swift - 从另一个 watch 应用打开 Apple Watch 应用

ios - IOS 的多重继承