如何返回和使用Swift类类型或方法的枚举

时间:2016-01-14 00:16:42

标签: swift enums swift-protocols

我正在构建一个简单的状态引擎,我想要一组可以在其间移动的状态。

我想要解决这个问题的方法是有一个可能的状态枚举,这些状态也可以定义代表该状态的相应类,这样我就可以动态地构造状态,如果我决定移动到那个州。

在下面的代码中,我尝试构建一个状态良好的状态对象的枚举。我遇到的问题是,如何将这个枚举的值作为我可以调用静态构造函数方法的类型来访问?在下面的代码中我得到的错误是,使用枚举值调用moveToState的尝试不代表StartupStates类型,它似乎......

所以问题是,为什么这不起作用,或者我可以通过其他方式获得类类型和/或类级别(静态)方法的枚举来调用构造函数?

public enum StartupStates<State> {
case Start(StartState)
case DownloadFiles(DownloadFilesState)
 }

 public protocol State {
   var stateEngine : StateEngine {get set}
 }

public class StateEngine
{
    var currentState : State?
    public func moveToState(newState : StartupStates<State>)
    {
    }
}

public class StartState : BaseState
{
    func doStateTasks()
    {
        // Move to next state, downloading files
        // ERROR IS HERE: 
        // "Cannot convert file of type '(DownloadFileState)->StartupStates<...>' to expected argument type 'StartupStates<State>'"

        stateEngine.moveToState(StartupStates.DownloadFiles)
    }
}

public class DownloadFilesState : BaseState
{
}


public class BaseState : State {
    public var stateEngine : StateEngine

    required public init( stateEngine : StateEngine ) {
        self.stateEngine = stateEngine
    }

    public static func stateCreator(stateEngine : StateEngine) -> Self {
        return self.init( stateEngine: stateEngine )
    }
}

3 个答案:

答案 0 :(得分:2)

字符串解决方案:

在这种情况下,您可以使用NSClassFromString。请考虑以下示例:

enum State: String {
    case StartState = "StartClass"
    case DownloadState = "DownloadClass"
    case BaseState = "BaseClass"

    var klass: AnyClass {
        return NSClassFromString(self.rawValue)!
    }
}

如果您正在寻找这种解决方案,请告诉我。

替代解决方案:

如果您不想依赖于键入字符串解决方案,那么您需要为类类型设置一个简单的switch语句:

class StartClass {}
class DownloadClass {}
class BaseClass {}

enum State {
    case StartState
    case DownloadState
    case BaseState

    var klass: AnyClass {
        switch self {
        case .StartState:
            return StartClass.self
        case .DownloadState:
            return DownloadClass.self
        case .BaseState:
            return BaseClass.self
        }
    }
}

答案 1 :(得分:0)

这个怎么样:

class StartState : BaseState {
    func doStateTasks() {        
        let download = DownloadFilesState(stateEngine: StateEngine())
        stateEngine.moveToState(.DownloadFiles(download))
   }
}

因为DownloadFiles枚举需要在枚举中定义DownloadFilesState个对象。

答案 2 :(得分:0)

如何使用完成处理程序而不是类类型?

protocol MyProtocol {}

class StartClass: MyProtocol {}
class DownloadClass: MyProtocol {}
class BaseClass: MyProtocol {}

enum State {
    case StartState
    case DownloadState
    case BaseState

    var completionHandler: () -> MyPrototype {
        switch self {
        case .StartState:
            return { return StartClass() }
        case .DownloadState:
            return { return DownloadClass() }
        case .BaseState:
            return { return BaseClass() }
        }
    }
}

从枚举值访问初始化的类。

var myState: State = .StartState
myState.completionHandler { initializedStartClass in
    InitializedStartClass.methods....
}