所选类实例的Swift扩展

Boo*_*oon 7 categories swift swift-extensions swift2

在Objective-C类别中,您可以通过在类中包含类别的标题来引入类别方法引入的扩展功能.

似乎所有Swift扩展都是在没有导入的情况下自动引入的.你如何在Swift中实现同样的目标?

例如:

extension UIView {
  // only want certain UIView to have this, not all
  // similar to Objective-C, where imported category header
  // will grant the capability to the class
  func extraCapability() {

  }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 8

定义一个将作为选择的协议,扩展应该是否可用:

protocol UIViewExtensions { }
Run Code Online (Sandbox Code Playgroud)

然后定义协议的扩展,但仅限于子类UIView(相反的方法不起作用):

extension UIViewExtensions where Self: UIView {
    func testFunc() -> String { return String(tag) }
}
Run Code Online (Sandbox Code Playgroud)

定义为具有协议的类也将具有扩展名:

class A: UIView, UIViewExtensions { }    
A().testFunc() //has the extension
Run Code Online (Sandbox Code Playgroud)

如果没有定义协议,它也没有扩展名:

class B: UIView {}    
B().testFunc() //execution failed: MyPlayground.playground:17:1: error: value of type 'B' has no member 'testFunc'
Run Code Online (Sandbox Code Playgroud)

UPDATE

由于协议扩展不执行类多态,如果需要覆盖函数,我唯一能想到的是子类:

class UIViewWithExtensions: UIView {
    override func canBecomeFocused() -> Bool { return true }
}
UIViewWithExtensions().canBecomeFocused() // returns true
Run Code Online (Sandbox Code Playgroud)

这也可以与扩展相结合,但我认为它不再有意义了.

  • +1请注意,在ObjC中,所有子类实际上都获得了扩展方法.只是编译器在编译时没有看到它们,并且如果你试图使用它们会产生警告.这很重要,因为在ObjC中打破这种保护很容易,并且ObjC有很多用例无法实现.这个答案不仅是正确的方法,而且实际上是OP的意思.*只有分配了此扩展名的*类型才能获得它,并且尝试在错误的位置使用它将产生错误,而不是警告.我甚至不称之为"解决方案协议".这只是一个协议. (3认同)