状态机 - 枚举是状态的选择吗?
我想将类静态变量作为状态,但 Objective C 不允许它
我尝试了 +(int)LOOPING_STATE
作为状态类,但它会失败
switch (myCurrentState) {
case [STATE_CLASS LOOPING_STATE]: <== received an error of "expression can't be put here"
return;
}
Is enum General the choice forwriting state code?
还有其他选项吗?在什么条件下应该使用这些选项?
提前致谢。
I would like to have class static variables as states, but Objective C disallowed it
I tried +(int)LOOPING_STATE
for state class, but it will fail in
switch (myCurrentState) {
case [STATE_CLASS LOOPING_STATE]: <== received an error of "expression can't be put here"
return;
}
Is enum generally the choice for writing state codes?
Are there any other options, and under what condition should those options be used?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这与 Objective-C 关系不大,而与 Objective-C 中的 C 关系更大。一般来说,使用枚举来表示状态机的状态应该优于普通整数。
不能在 switch 中使用类的原因是 switch 语句的 case 标签中使用的表达式的值需要在编译时已知。假设 [STATE_CLASS LOOPING_STATE] 是类方法的调用,编译器在编译时无法安全地知道该表达式的结果,因此将拒绝生成 switch 语句。
为什么编译器需要在编译时知道用于 case 标签的表达式的结果? switch 语句背后的想法是比一系列语义上等效的 if/else if 块更有效。这是通过将 switch 语句转换为具有无条件跳转的调度表来实现的,而 if/else if 解决方案需要大量条件跳转。人们很容易猜到,条件跳转从根本上与现代流水线 CPU 设计不一致,因为它们可能会导致整个流水线被刷新。 (现代 CPU 试图通过复杂的分支预测来进行补偿,但如果我们能够完全避免这个问题,那就更好了,对吧?)
但是,首先要保证正确,其次才是加快速度。
This has little to do with Objective-C but more with the C in Objective-C. In general, using an enum to represent the states of your state machine should be preferred over plain integers.
The reason you can't use classes in a switch is that the value of the expressions used in the case labels of a switch statement need to be known at compile time. Assuming
[STATE_CLASS LOOPING_STATE]
is an invocation of a class method, the compiler can't safely know the result of that expression at compile time, and will thus refuse generating a switch statement.Why does the compiler require knowing the result of expressions used for case labels at compile time? The idea behind a switch statement is to be more efficient than a series of semantically equivalent if/else if blocks. This is achieved by translating a switch statement into a dispatch table with an unconditional jump, whereas the if/else if solution requires lots of conditional jumps. As one can easily guess, conditional jumps are fundamentally at odds with modern pipelined CPU designs since they may cause the entire pipeline to be flushed. (Modern CPUs try to compensate with sophisticated branch prediction, but it would be better if we can avoid the issue altogether, right?)
But then, getting it right comes first, making it fast second.
如果这个状态机需要快速,那么枚举就是最佳选择。但是,如果您想要一种面向对象的方式来执行此操作,则每个状态的功能将是状态对象本身的方法。因此,您将完全取消 switch/if 语句。您的状态机循环看起来像这样:
inputs
是状态转换的输入数据,actions
是一个块或一个选择器或一个NSInitation
> 或者告诉国家在过渡期间要做什么的东西。If this state machine needs to be fast, enums are the way to go. However, if you want an object oriented way of doing this, the functionality of each state would be a method of the state object itself. Thus you would do away with the switch/if statement altogether. Your state machine's loop would look something like this:
inputs
is the input data for the state transition,actions
is a block or a selector or anNSInvocation
or something that tells the state what to do during the transition.