用于泛型类的Swift委托协议 [英] Swift delegate protocol for generic class

查看:137
本文介绍了用于泛型类的Swift委托协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类, StateMachine ,这是通用的,允许将不同的状态集合实现为例如枚举。我想使用 StateMachineDelegate 协议通知代理机构状态机进入新的状态。

I have a class, StateMachine, that is generic to allow for different sets of states to be implemented as, for example, an enum. I want to use a StateMachineDelegate protocol to notify a delegate when the state machine enters a new state.

但是因为委托协议也是类型要求通用的,所以不起作用。错误显示在哪里声明委托属性。

But this doesn't work since the delegate protocol is also generic with type requirements. The error shows where the delegate property is declared.

protocol StateType: Hashable {}

protocol StateMachineDelegate: class {
    typealias S: StateType
    func stateMachine(stateMachine: StateMachine<S>, 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)
        ...
    }
}





我需要以某种方式关联 StateMachineDelegate.S == S StateMachine 类,但我不知道如何做到这一点,或者如果可能的话。我试过:



I need to somehow associate that StateMachineDelegate.S == S in the StateMachine class, but I'm not sure how to do this, or if it's possible. I tried:

class StateMachine<S: StateType, D: StateMachineDelegate where D.S == S> {
    ...
    weak var delegate: D?
    ...
}

但是我试图重做协议正确声明通用类型 StateMachine 。而在创建一个 StateMachine 时,就不得不先声明该委托的类型。

but then I get stuck trying to rework the protocol to properly declare the generic type of StateMachine. And it doesn't seem right to have to declare the type of the delegate up front when creating a StateMachine.

推荐答案

看看这个解决方法是否符合您的需求,它使用 @autoclosure 来摆脱递归泛型定义的问题: / p>

See if this workaround is ok for your needs, it uses @autoclosure to get rid of a problem with recursive generic definitions:

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

顺便说一下,如果你得到砂光机,可能你不需要得到 newState
我使用可打印代替 Hashable 作为示例。

By the way, consider that if you get the sander, probably you don't need to get the newState passed. I used Printable in place of Hashable for the example.

这篇关于用于泛型类的Swift委托协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆