Swift实现多个协议与委托

问题描述:

我想实现一个协议,它本身继承多个协议,都有一个委托成员。有没有干净的方式来做到这一点,而不需要为每个协议的委托使用不同的名称?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>? 
} 
+0

委托是符合协议的对象。我想不出为什么它有一个代表。 – vikingosegundo 2014-11-23 03:17:33

+0

@vikingosegundo我可以看到你的观点,即委托属于实现而不是协议。目前我只是从协议中删除委托属性,并且只在实现中声明协议。如果你想发布这个作为答案,我会很乐意接受它。 – robhasacamera 2014-11-23 18:33:12

在你的代码中,delegate只是一个普通的属性。您可以拥有多个协议,声明具有相同名称和相同类型的属性,并有一个类直接或间接实现它。

如果不同的协议定义了一个具有相同名称但类型不同的属性,那么您将无法编译它,因为编译器会抱怨重新声明属性和类没有确认其中一个协议。

有2种可能的解决方案。最明显的是避免使用在其他协议中使用的概率很高的名称 - delegate是一个典型情况。使用不同的命名惯例,如protocol1DelegatedataSourceDelegateapiCallDelegate

的第二溶液由具有方法替换性质。例如:

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个协议使用相同的函数签名(名称,参数和返回类型),那么在类中实现时,您将实现该函数一次 - 在某些情况下可能是想要的行为,但在其他情况下可能不需要。

+0

我真的很想避免让不同名称的代表出现,我已经做到了这一点,并且效果不佳。另外,我并不知道你可能会重载Swift中的函数返回值。但是,我试图超载的财产,并没有奏效。这意味着即使外部方法名称与内部相同,我仍然需要两个名称不同的属性来跟踪它们。 – robhasacamera 2014-11-23 18:29:28

解决方案可能是使用协议扩展(请检查extension Combined)。好处是Combined只声明delegateoneDelegatetwoDelegate是交叉实现计算。不幸的是,要求将三个变量暴露在课堂外,这可能是不方便的。

// 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)? 

您现在可以使用这两种协议。