Swift使用一个代理实现多个协议
我正在尝试实现一个协议,该协议本身继承了多个协议,这两个协议都有一个委托成员。是否有一种干净的方法可以做到这一点,而不需要为每个协议的委托使用不同的名称Swift使用一个代理实现多个协议,swift,delegates,protocols,Swift,Delegates,Protocols,我正在尝试实现一个协议,该协议本身继承了多个协议,这两个协议都有一个委托成员。是否有一种干净的方法可以做到这一点,而不需要为每个协议的委托使用不同的名称 protocol ProtocolOne { var delegate: ProtocolOneDelegate? } protocol ProtocolTwo { var delegate: ProtocolTwoDelegate? } protocol CombinedProtocol: ProtocolOne, Pro
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>?
}
协议原型{
变量代理:ProtocolOneDelegate?
}
协议二{
变量委托:ProtocolTwoDelegate?
}
协议组合协议:ProtocolOne,Protocol2{
}
协议组合删除:ProtocolOneDelegate,ProtocolTwoDelegte{
}
类ProtocolImpl:CombinedProtocol{
//我如何在这里实现委托?
//我尝试了以下选项但没有成功:
变量代理:组合删除门?
var代理:协议?
}
在代码中,委托
只是一个普通属性。可以使用多个协议声明具有相同名称和相同类型的属性,并使用一个类直接或间接实现该属性
如果不同的协议使用相同的名称但不同的类型定义了一个属性,您将无法使其编译,因为编译器将抱怨重新声明一个属性,而类不符合其中一个协议
有两种可能的解决方案。最明显的一点是避免使用在其他协议中使用概率很高的名称-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考虑具有相同参数列表但返回类型不同的函数作为重载。但是请注意,如果两个协议使用相同的函数签名(名称、参数和返回类型),在类中实现时,您将实现该函数一次-在某些情况下,这可能是需要的行为,但在其他情况下是不需要的。
解决方案可能是使用协议扩展(检查扩展组合
)。好处是Combined
只声明delegate
和oneDelegate
和twodedelegate
是跨实现计算的。不幸的是,要求将这三个变量暴露在类之外,这可能会带来不便
// 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()
您应该能够将它们合并为一个:
var delegate: (ProtocolOneDelegate & ProtocolTwoDelegate)?
您现在可以使用这两种协议。委托是符合协议的对象。我想不出它有委托的原因。@vikingosegundo我能理解你的观点,委托属于实现而不是协议。目前,我只是从协议中删除了委托属性,并且只在实现中声明了协议。如果你想把这个作为一个答案,我很乐意接受。我真的不想让代表们有各种各样的名字,我已经做过了,这已经是过去了,而且效果不好。另外,我不知道您可能会在Swift中重载返回函数。但是,我尝试了重载属性,但没有成功。这意味着,即使外部的方法名与内部的方法名相同,我仍然需要两个名称不同的属性来跟踪这两个属性。这是否存在编译器限制?我有一个稍微复杂一点的例子,
ProtocolImpl
,在本例中,充当委托本身,并将delegate
属性重定向到self,而这不会编译。这里有一个例子。