国家机器 - 枚举是国家的选择吗?

时间:2011-10-28 10:04:31

标签: objective-c enums state

我想将类静态变量作为状态,但是Objective C禁止它

我为状态类尝试了+(int)LOOPING_STATE,但它在

中失败了
switch (myCurrentState) {
case [STATE_CLASS LOOPING_STATE]:   <== received an error of "expression can't be put here"
return;
}

枚举通常是编写州代码的选择吗?

是否还有其他选择,在什么条件下应该使用这些选项?

提前致谢。

2 个答案:

答案 0 :(得分:4)

这与Objective-C几乎没有关系,但更多与Objective-C中的C有关。通常,使用枚举来表示状态机的状态应优先于普通整数。

您不能在switch中使用类的原因是需要在编译时知道switch语句的case标签中使用的表达式的值。假设[STATE_CLASS LOOPING_STATE]是一个类方法的调用,编译器无法在编译时安全地知道该表达式的结果,因此将拒绝生成switch语句。

为什么编译器需要在编译时知道用于案例标签的表达式的结果? switch语句背后的想法是比一系列语义上等效的if / else if块更有效。这是通过将switch语句转换为具有无条件跳转的调度表来实现的,而if / else if解决方案需要大量的条件跳转。可以很容易地猜到,条件跳转基本上与现代流水线CPU设计不一致,因为它们可能导致整个管道被冲洗。 (现代CPU试图通过复杂的分支预测进行补偿,但如果我们完全避免这个问题会更好,对吗?)

然而,首先要做到这一点,首先要做到第二。

答案 1 :(得分:3)

如果这台状态机需要快速,那么枚举就是最佳选择。但是,如果您希望以面向对象的方式执行此操作,则每个状态的功能将是状态对象本身的方法。因此,您将完全取消switch / if语句。你的状态机的循环看起来像这样:

-(void) run
{
    State* currentState;

    currentState = [self startState];
    while (currentState != [self stopState])
    {
        currentState = [currentState transitionWitInput: inputs 
                                                actions: actions];
    }
}

inputs是状态转换的输入数据,actions是块或选择器或NSInvocation或者告诉状态在转换期间要做什么的东西。