2011-10-28 43 views
2

我想有类的静态变量的状态,但目标C不允许它状态机 - 是枚举状态的选择?

我试图+(int)LOOPING_STATE的状态类,但在

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

是枚举一般写状态代码选择它会失败?

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

在此先感谢。

回答

3

如果这个状态机需要很快,枚举是要走的路。然而,如果你想要一个面向对象的方式来做到这一点,每个状态的功能将是状态对象本身的一种方法。因此,你会完全不用开关/ if语句。你的状态机的循环会是这个样子:

-(void) run 
{ 
    State* currentState; 

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

inputs是国家转变的输入数据,actions是块或选择,或者告诉状态的过程中如何去做的NSInvocation什么的。

4

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

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

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

但是,然后,把它放在第一位,使其成为第二位。

+0

很多thx的解释。我讨厌由枚举定义的全局常量,有没有办法让状态在一个类中保持不变?还是有其他的选择去做我想要的?谢谢! – Unreality

+2

声明一个枚举在你的状态机的头部应该没问题,毕竟状态的数量应该是有限的。我没有看到全局定义这些常量的枚举问题(毕竟,你只对符号感兴趣,而不是数值)。 –