Swift delegate protocol for generic class
我有一个类
但这是行不通的,因为委托协议对于类型要求也是通用的。该错误显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | protocol StateType: Hashable {} protocol StateMachineDelegate: class { typealias S: StateType func stateMachine(stateMachine: StateMachine, didEnterState newState: S) } class StateMachine<S: StateType> { typealias State = S weak var delegate: StateMachineDelegate? //~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~ //Protocol 'StateMachineDelegate' can only be used as a generic constraint because it has Self or associated type requirements var currentState: State {...} init(initialState: State) {...} func applyState(toState: State) -> Bool { ... currentState = toState delegate?.stateMachine(self, didEnterState: toState) ... } } |
我需要以某种方式将
1 2 3 4 5 | class StateMachine<S: StateType, D: StateMachineDelegate where D.S == S> { ... weak var delegate: D? ... } |
,但是随后我陷入尝试重新修改协议以正确声明
看看这种解决方法是否可以满足您的需要,它使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class StateMachine<S: Printable, D: StateMachineDelegate where S == D.StateType> { var currentState: S { didSet { // The observer if let delegate = self.delegate { delegate.stateMachine(self, didEnterState: self.currentState) } } } var delegate: D? init(initialState: S) { self.currentState = initialState } } protocol StateMachineDelegate: class { typealias StateType: Printable // Workaround with autoclosure func stateMachine(machine: @autoclosure() -> StateMachine<StateType, Self>, didEnterState newState: StateType) } final class ADelegate: StateMachineDelegate { typealias StateType = Int func stateMachine(machine: @autoclosure () -> StateMachine<StateType, ADelegate>, didEnterState newState: StateType) { // Need to _unbox_ the sander from the closure let sender = machine() println(newState) println("State from sender: \\(sender.currentState)") } } let stateMachine = StateMachine<Int, ADelegate>(initialState: 24) stateMachine.delegate = ADelegate() stateMachine.currentState = 50 |
顺便说一句,请考虑,如果您使用的是砂光机,则可能不需要通过
在示例中,我用
我认为这只是一个名称冲突问题...请尝试以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | protocol StateType: Hashable {} protocol StateMachineDelegate: class { typealias State: StateType func stateMachine(stateMachine: StateMachine<State>, didEnterState newState: State) } class StateMachine<S: StateType> { typealias State = S weak var delegate: StateMachineDelegate? var currentState: State {...} init(initialState: State) {...} func applyState(toState: State) -> Bool { ... currentState = toState delegate?.stateMachine(self, didEnterState: toState) ... } } |
您需要声明协议中定义的泛型类型的名称应在符合该类型的类中。