如何在Objective-C中制作基本的有限状态机 [英] How to Make a Basic Finite State Machine in Objective-C

查看:76
本文介绍了如何在Objective-C中制作基本的有限状态机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建FSM以控制(iphone SDK)目标c中的计时器.我觉得这是必要的步骤,因为否则我将以包含if-then语句页面的讨厌的意大利面条代码结尾.复杂性,不可读取性以及添加/更改功能的困难使我尝试使用这种更正式的解决方案.

I am attempting to build an FSM to control a timer in (iphone sdk) objective c. I felt it was a necessary step, because I was otherwise ending up with nasty spaghetti code containing pages of if-then statements. The complexity, non-readability, and difficulty of adding/changing features lead me to attempt a more formal solution like this.

在应用程序的上下文中,计时器的状态确定与NSManagedObjects,Core Data等的一些复杂交互.我暂时将所有功能都保留了下来,以期清楚地了解FSM代码.

In the context of the application, the state of the timer determines some complex interactions with NSManagedObjects, Core Data, and so forth. I have left all that functionality out for now, in an attempt to get a clear view of the FSM code.

问题是,我无法在Obj-C中找到此类代码的任何示例,而且我对如何从所使用的C ++示例代码中转换出该代码也不太确定. (我根本不了解C ++,所以涉及到一些猜测.)我将这种版本的状态模式设计基于本文:

The trouble is, I cannot find any examples of this sort of code in Obj-C, and I am not so confident about how I have translated it from the C++ example code I was using. (I don't know C++ at all, so there is some guessing involved.) I am basing this version of a state pattern design on this article: http://www.ai-junkie.com/architecture/state_driven/tut_state1.html. I'm not making a game, but this article outlines concepts that work for what I'm doing.

为了创建代码(如下所述),我必须学习很多新概念,包括obj-c协议等等.因为这些对我来说都是新的,所以就像状态设计模式一样,我希望获得有关此实现的一些反馈.这是您在obj-c中有效使用协议对象的方式吗?

In order to create the code (posted below), I had to learn a lot of new concepts, including obj-c protocols, and so forth. Because these are new to me, as is the state design pattern, I'm hoping for some feedback about this implementation. Is this how you work with protocol objects effectively in obj-c?

以下是协议:

@class Timer;
@protocol TimerState 

-(void) enterTimerState:(Timer*)timer;
-(void) executeTimerState:(Timer*)timer;
-(void) exitTimerState:(Timer*)timer;

@end

这是Timer对象(以最简化的形式)头文件:

Here is the Timer object (in its most stripped down form) header file:

@interface Timer : NSObject
{       
    id<TimerState> currentTimerState;
    NSTimer *secondTimer;
    id <TimerViewDelegate> viewDelegate;

    id<TimerState> setupState;
    id<TimerState> runState;
    id<TimerState> pauseState;
    id<TimerState> resumeState;
    id<TimerState> finishState;
}

@property (nonatomic, retain) id<TimerState> currentTimerState;
@property (nonatomic, retain) NSTimer *secondTimer;
@property (assign) id <TimerViewDelegate> viewDelegate;

@property (nonatomic, retain) id<TimerState> setupState;
@property (nonatomic, retain) id<TimerState> runState;
@property (nonatomic, retain) id<TimerState> pauseState;
@property (nonatomic, retain) id<TimerState> resumeState;
@property (nonatomic, retain) id<TimerState> finishState;

-(void)stopTimer;
-(void)changeState:(id<TimerState>) timerState;
-(void)executeState:(id<TimerState>) timerState;
-(void) setupTimer:(id<TimerState>) timerState;

以及Timer对象的实现:

And the Timer Object implementation:

#import "Timer.h"
#import "TimerState.h"
#import "Setup_TS.h"
#import "Run_TS.h"
#import "Pause_TS.h"
#import "Resume_TS.h"
#import "Finish_TS.h"


@implementation Timer

@synthesize currentTimerState;
@synthesize viewDelegate;
@synthesize secondTimer;

@synthesize setupState, runState, pauseState, resumeState, finishState;

-(id)init
{
    if (self = [super init])
    {
        id<TimerState>  s = [[Setup_TS alloc] init];
        self.setupState = s;
        //[s release];

        id<TimerState> r = [[Run_TS alloc] init];
        self.runState = r;
        //[r release];

        id<TimerState> p = [[Pause_TS alloc] init];
        self.pauseState = p;
        //[p release];

        id<TimerState> rs = [[Resume_TS alloc] init];
        self.resumeState = rs;
        //[rs release];

        id<TimerState> f = [[Finish_TS alloc] init];
        self.finishState = f;
        //[f release];  
    }
    return self;
}

-(void)changeState:(id<TimerState>) newState{
    if (newState != nil)
    {
        [self.currentTimerState exitTimerState:self];
        self.currentTimerState = newState;
        [self.currentTimerState enterTimerState:self];
        [self executeState:self.currentTimerState];
    }
}

-(void)executeState:(id<TimerState>) timerState
{
    [self.currentTimerState executeTimerState:self];    
}

-(void) setupTimer:(id<TimerState>) timerState
{
    if ([timerState isKindOfClass:[Run_TS class]])
    {
        secondTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(currentTime) userInfo:nil repeats:YES];
    }
    else if ([timerState isKindOfClass:[Resume_TS class]])
    {
        secondTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(currentTime) userInfo:nil repeats:YES];
    }
}

-(void) stopTimer
{   
    [secondTimer invalidate];
}

-(void)currentTime
{   
    //This is just to see it working. Not formatted properly or anything.
    NSString *text = [NSString stringWithFormat:@"%@", [NSDate date]];
    if (self.viewDelegate != NULL && [self.viewDelegate respondsToSelector:@selector(updateLabel:)])
    {
        [self.viewDelegate updateLabel:text];
    }
}
//TODO: releases here
- (void)dealloc
{
    [super dealloc];
}

@end

不要担心此类中缺少某些内容.它并没有做任何有趣的事情.我目前只是在努力使语法正确.当前它可以编译(并且可以工作),但是isKindOfClass方法调用会引起编译器警告(协议中找不到该方法).无论如何,我不确定自己是否要使用isKindOfClass.我正在考虑给每个id<TimerState>对象一个名称字符串,然后改用它.

Don't worry that there are missing things in this class. It doesn't do anything interesting yet. I'm currently just struggling with getting the syntax correct. Currently it compiles (and works) but the isKindOfClass method calls cause compiler warnings (method is not found in protocol). I'm not really sure that I want to use isKindOfClass anyway. I was thinking of giving each id<TimerState> object a name string and using that instead.

另一方面,所有这些id<TimerState>声明最初都是TimerState *声明.保留它们作为属性似乎很有意义.不确定id<TimerState>是否有意义.

On another note: all those id<TimerState> declarations were originally TimerState * declarations. It seemed to make sense to retain them as properties. Not sure if it makes sense with id<TimerState>'s.

以下是状态类之一的示例:

Here is an example of one of the state classes:

#import "TimerState.h"


@interface Setup_TS : NSObject <TimerState>{

}

@end

#import "Setup_TS.h"
#import "Timer.h"

@implementation Setup_TS

-(void) enterTimerState:(Timer*)timer{
    NSLog(@"SETUP: entering state");
}
-(void) executeTimerState:(Timer*)timer{
    NSLog(@"SETUP: executing state");
}
-(void) exitTimerState:(Timer*)timer{
    NSLog(@"SETUP: exiting state");
}

@end

同样,到目前为止,除了宣布它所处的状态(或子状态)外,它什么也没做.但这不是重点.

Again, so far it doesn't do anything except announce that what phase (or sub-state) it's in. But that's not the point.

我希望在这里学习的是这种架构是否以obj-c语言正确地组成.我遇到的一个特定问题是在计时器的init函数中创建id对象.如您所见,我评论了这些发行版,因为它们引起了协议中找不到发行版"的警告.我不确定该如何处理.

What I'm hoping to learn here is whether this architecture is composed correctly in the obj-c language. One specific problem I'm encountering is the creation of the id objects in the timer's init function. As you can see, I commented out the releases, because they were causing a "release not found in protocol" warning. I wasn't sure how to handle that.

我不需要的是关于此代码过大或毫无意义的形式主义等的注释.即使那些想法是正确的,也值得我学习.如果有帮助,可以将其视为obj-c中FSM的理论设计.

What I don't need is comments about this code being overkill or meaningless formalism, or whatever. It's worth me learning this even it those ideas are true. If it helps, think of it as a theoretical design for an FSM in obj-c.

在此先感谢您提供任何有用的评论.

Thank you in advance for any helpful comments.

(这没有太大帮助: Objective-C中的有限状态机)

推荐答案

使用协议作为类型修饰符时,可以提供以逗号分隔的协议列表.因此,要摆脱编译器警告,您需要做的就是将NSObject添加到协议列表中,如下所示:

When you use a protocol as a type-modifier, you can provide a comma-separated list of protocols. So all you need to do to get rid of the compiler warning is add NSObject to the protocol list like so:

- (void)setupTimer:(id<TimerState,NSObject>) timerState {

    // Create scheduled timers, etc...
}

这篇关于如何在Objective-C中制作基本的有限状态机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆