协议是否可以用Swift中实现者定义的函数进行扩展



示例:

游乐场:github

protocol A: class {}
extension A {
func someFunc() {
print("1")
}
}
class B {
weak var delegate: A?

func someTrigger() {
delegate?.someFunc()
}
}
class C: A {
lazy var b: B = {
let b = B()
b.delegate = self
return b
}()

func someFunc() {
print("2")
}

init() {
b.someTrigger()
}
}
let c = C()
/// printed 1

问题

在上面你可以看到一个例子来更好地理解这个问题。所以问题是:协议可以用实现者(实现协议的类(定义的函数来扩展吗?在我看来,示例代码的结果是出乎意料的。是否可以在没有协议继承的情况下以某种方式完成?


更新

我无法在协议A中实现someFunc()(它是UIKit协议(。这就是为什么我考虑恰恰这种体系结构/配置。

protocol A: class {
func someFunc()
}
extension A {
func someFunc() {
print("1")
}
}
class AA: A { }

现在在AA类中,您可以使用默认实现(在扩展中(,也可以用自定义实现覆盖它。因此,您必须在协议本身中定义一个函数,因为它是接口。

但不在协议中定义它是没有意义的,这只是一个糟糕的设计,因为protocol=类上的接口。如果你想使用函数someFunc(),你可以立即执行,而不需要重新定义它,因为自从你实现了一个协议以来,它就已经在那里了。

考虑在不暴露协议本身函数的情况下扩展协议,就像扩展要在其中实现该协议的类一样。

更新:

protocol MyProtocol: class {
func myFunc()
} 
extension MyProtocol where Self: UIKitProtocol {
func myFunc() {
}
}
class AA: UIKitProtocol, MyProtocol { }

定义您自己的协议

经过我刚才尝试的一些测试,您必须在A协议声明中公开someFunc()函数,才能像这样调用C类的someFunc()函数:

protocol A: class {
func someFunc()
}

然后你会得到以下结果:

let c = C()
/// printed 2

更新:您可以创建另一个实现A协议的类,并将其用于默认的someFunc()实现,而不是向协议A添加扩展:

class D: A {
func someFunc() {
print("1")
}
}
class B {
weak var delegate: D?

func someTrigger() {
delegate?.someFunc()
}
}
class C: D {
lazy var b: B = {
let b = B()
b.delegate = self
return b
}()

override func someFunc() {
print("2")
}

override init() {
super.init()
b.someTrigger()
}
}

这也会有你预期的结果。

最新更新