我想将类静态变量作为状态,但是Objective C禁止它
我为状态类尝试了+(int)LOOPING_STATE
,但它在
switch (myCurrentState) {
case [STATE_CLASS LOOPING_STATE]: <== received an error of "expression can't be put here"
return;
}
枚举通常是编写州代码的选择吗?
是否还有其他选择,在什么条件下应该使用这些选项?
提前致谢。
答案 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
或者告诉状态在转换期间要做什么的东西。