Take the 2-minute tour ×

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.

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.

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.

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?

Here is the protocol:

@class Timer;
@protocol TimerState 

-(void) enterTimerState:(Timer*)timer;
-(void) executeTimerState:(Timer*)timer;
-(void) exitTimerState:(Timer*)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)changeState:(id<TimerState>) timerState;
-(void)executeState:(id<TimerState>) timerState;
-(void) setupTimer:(id<TimerState>) timerState;

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;

    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];

    [self.currentTimerState executeTimerState:self];    

    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]])

-(void) stopTimer
    [secondTimer invalidate];

    //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];


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.

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>{



#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");


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.

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.

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.

(this didn't help too much: Finite State Machine in Objective-C)

share|improve this question

5 Answers 5

up vote 7 down vote accepted

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...
share|improve this answer
You can also have a protocol conform to another protocol so that it's not necessary to mention both every time — declare it like @protocol TimerState <NSObject>. This tells the compiler than all TimerState objects must also conform to the NSObject protocol. –  Chuck Mar 9 '10 at 22:49
Which would almost certainly what you'd want to do in this case. Excellent point. –  jlehr Mar 9 '10 at 23:02
That certainly does make the compiler happy. –  mwt Mar 9 '10 at 23:29

I suggest using State Machine Compiler, it will output Objective-C code. I have had good success in Java and Python using this.

You shouldn't be writing state machine code by hand, you should be using something to generate the code for you. SMC will generate clean clear code you can then look at if you want to learn from it, or you can just use it and be done with it.

share|improve this answer
Oh. I didn't know about this. –  Warren P Mar 9 '10 at 22:06
That is interesting, although it doesn't really address my question. –  mwt Mar 9 '10 at 22:10
This is the best answer I have seen on SO yet –  Nektarios Feb 28 '11 at 5:53
one problem I've faced with that compiler is that it does not allow to call fsm's transition methods being inside the actions' methods ("action" in the notation of SMC) –  peetonn Apr 7 '12 at 9:59
@mwt it says "How to Make a Basic Finite Machine ..." the point of my answer is the language is irrelevant and this type of code should declared in some DSL and be generated not built and maintained by hand. –  Jarrod Roberson Jul 13 '12 at 18:03

If you want a very simple, Objective-C implementation of a State Machine I've just released TransitionKit, which provides a well designed API for implementing state machines. It's thoroughly tested, well documented, very easy to use, and doesn't require any code generation or external tools.

share|improve this answer

I'd suggest checking out Statec it's got a nice little dsl for doing FSM and outputs ObjC code. It's sort of like mogenerator for state machines.

share|improve this answer

I am rather new at Objective-C, but I would suggest that you look at straight ANSI C implementation for the State Machine.

Just because you're using Cocoa doesn't mean you have to use Objective-C messages here.

In ANSI C, a state machine implementation can be very straightforward and readable.

My last implementation in C of a FSM specified #define STATE_x or enumerate types for the states and had a table of pointers to functions to execute each state.

share|improve this answer
The ai-junkie.com article mentioned above discusses why the design I'm attempting above is superior to the table-of-functions design. I don't know that it actually is a better way to go, but his ideas are worth reading. –  mwt Mar 9 '10 at 22:09
I guess I should say "supposedly better." –  mwt Mar 9 '10 at 23:28

Your Answer


