Swift使用委托实现多个协议
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift使用委托实现多个协议相关的知识,希望对你有一定的参考价值。
我正在尝试实现一个本身继承多个协议的协议,这些协议都有一个委托成员。是否有一种干净的方法来执行此操作,而不需要为每个协议的委托使用不同的名称?
protocol ProtocolOne {
var delegate: ProtocolOneDelegate?
}
protocol ProtocolTwo {
var delegate: ProtocolTwoDelegate?
}
protocol CombinedProtocol: ProtocolOne, ProtocolTwo {
}
protocol CombinedDelegate: ProtocolOneDelegate, ProtocolTwoDelegte {
}
class ProtocolImpl: CombinedProtocol {
// How can I implement delegate here?
// I've tried the following options without success:
var delegate: CombinedDelegate?
var delegate: protocol<ProtocolOneDelegate, ProtocolTwoDelegate>?
}
答案
你应该能够把它们合二为一:
var delegate: (ProtocolOneDelegate & ProtocolTwoDelegate)?
您现在可以使用这两种协议。
另一答案
在您的代码中,delegate
只是一个普通的属性。您可以使用多个协议声明具有相同名称和相同类型的属性,并让类直接或间接地实现它。
如果不同的协议定义了具有相同名称但类型不同的属性,则您将无法进行编译,因为编译器会抱怨重新声明属性和类不确认其中一个协议。
有2种可能的解决方案。最明显的一个是避免使用在其他协议中使用的概率很高的名称 - delegate
是一个典型案例。使用不同的命名约定,例如protocol1Delegate
,dataSourceDelegate
,apiCallDelegate
等。
第二种解决方案包括用方法替换属性。例如:
protocol P1 {
func test() -> String?
}
protocol P2 {
func test() -> Int?
}
protocol P3: P1, P2 {
}
class Test : P3 {
func test() -> String? { return nil }
func test() -> Int? { return nil }
}
Swift考虑具有相同参数列表但不同返回类型的函数作为重载。但请注意,如果2个协议使用相同的函数签名(名称,参数和返回类型),则在类中实现时,您将实现该函数一次 - 在某些情况下可能是所需行为,但在其他情况下则不需要。
另一答案
解决方案可能是使用协议扩展(检查extension Combined
)。好处是Combined
只声明delegate
和oneDelegate
和twoDelegate
计算交叉实现。不幸的是,要求将三个变量暴露在课堂外,这可能会带来不便。
// MARK: - Delegates protocols
protocol OneDelegate {
func oneDelegate(one: One)
}
protocol TwoDelegate {
func twoDelegate(two: Two)
}
protocol CombinedDelegate: OneDelegate, TwoDelegate {
func combinedDelegate(combined: Combined)
}
// MARK: - Model protocols
protocol One: class {
var oneDelegate: OneDelegate? { get }
}
protocol Two: class {
var twoDelegate: TwoDelegate? { get }
}
protocol Combined: One, Two {
var delegate: CombinedDelegate? { get }
}
extension Combined {
var oneDelegate: OneDelegate? {
return delegate
}
var twoDelegate: TwoDelegate? {
return delegate
}
}
// MARK: - Implementations
class Delegate: CombinedDelegate {
func oneDelegate(one: One) {
print("oneDelegate")
}
func twoDelegate(two: Two) {
print("twoDelegate")
}
func combinedDelegate(combined: Combined) {
print("combinedDelegate")
}
}
class CombinedImpl: Combined {
var delegate: CombinedDelegate?
func one() {
delegate?.oneDelegate(self)
}
func two() {
delegate?.twoDelegate(self)
}
func combined() {
delegate?.combinedDelegate(self)
}
}
// MARK: - Usage example
let delegate = Delegate()
let protocolImpl = CombinedImpl()
protocolImpl.delegate = delegate
protocolImpl.one()
protocolImpl.two()
protocolImpl.combined()
以上是关于Swift使用委托实现多个协议的主要内容,如果未能解决你的问题,请参考以下文章