Take the 2-minute tour ×

I have been researching for days on how to do this and nobody has an answer.

I am creating an app with 5 timers on the same view. I need to create a timer that counts down from "15:00" (minutes and seconds), and, another that counts down from "2:58" (minutes and seconds). The 15 minute timer should not repeat, but it should stop all other timers when it reaches "00:00." The "2:58" timer should repeat until the "15:00" or "Game Clock" reaches 0. Right now, I have scrapped almost all of my code and I'm working on the "2:58" repeating timer, or "rocketTimer."

Does anyone know how to do this?

EDIT 2: My simulator will not even run the app so I currently have no idea if the timer is actually working or not, but from my previous attempts, it has not worked. It doesn't show up in the format that I want and it counts down by 2's (from the last time it actually worked). The problem is, also, that I'm not fluent in objective-C. I can write pseudocode all day, just like everyone else, but I cannot put what I want into code because I do not fully understand the NSTimer.


In my output, I get this error "terminate called after throwing an instance of 'NSException'"

and this error?

my error

Here is my code:

    #import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController {

    //Rocket Timer
    int totalSeconds;
    bool timerActive;
    NSTimer *rocketTimer;
    IBOutlet UILabel *rocketCount;

    int newTotalSeconds;
    int totalRocketSeconds;
    int minutes;
    int seconds;


- (IBAction)Start;


and my .m

    #import "FirstViewController.h"

@implementation FirstViewController

- (NSString *)timeFormatted:(int)newTotalSeconds

    int seconds = totalSeconds % 60; 
    int minutes = (totalSeconds / 60) % 60; 

    return [NSString stringWithFormat:@"%i:%02d"], minutes, seconds; 

-(IBAction)Start {

    newTotalSeconds = 178; //for 2:58

    newTotalSeconds = newTotalSeconds-1;

    rocketCount.text = [self timeFormatted:newTotalSeconds];

    if(timerActive == NO){

        timerActive = YES;
        newTotalSeconds = 178;

      [rocketTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerLoop) userInfo:nil repeats:YES];


        timerActive = NO;
        [rocketTimer invalidate];
        rocketTimer = nil;



-(void)timerLoop:(id)sender {

    totalSeconds = totalSeconds-1;

    rocketCount.text = [self timeFormatted:totalSeconds];


- (void)dealloc
    [super dealloc];

    [rocketTimer release];


- (void)didReceiveMemoryWarning
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];


- (void)viewDidLoad
    [super viewDidLoad];

    timerActive = NO;

- (void)viewDidUnload
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);

share|improve this question
What have you achieved yet and what not? From what i see here, it should update the label properly. Does it? Or is the problem it's not repeating? –  Erik Dolor Mar 19 '11 at 15:56
add comment

3 Answers

There are a few problems with your code!
The bad news is, that none of them relate to the crash you are seeing.

The first and most obvious problem

Actually, you never stop your countdown!

After you've scheduled the timer in Start, your timerLoop:-method will be called every second. But you forgot to check whether totalSeconds has become negative...

The second problem

-(NSString *)timeFormatted:(int)newTotalSeconds will not work the way you expect it to! Actually, I'm pretty damn sure that Xcode gives you a compiler warning stating "Local declaration of 'newTotalSeconds' hides instance variable".
Try it out: In Start, replace the line rocketCount.text = [self timeFormatted:newTotalSeconds]; with the line rocketCount.text = [self timeFormatted:42]; and set a breakpoint after it.

The third problem (which actually are a couple of problems in one place)

Your dealloc is plain wrong:
First and foremost, it's not the best idea to have any calls after [super dealloc]. Second, "ur doin it wrong": Considering your Start-method, you don't own the timer so you must not release it. Instead, if the timer was still valid, you'd need to invalidate it. But this won't even become a problem, because as long as rocketTimer is scheduled, your viewController will not be dealloced (unless you have an error within your memory-management elsewhere). I've written a fairly complete example explaining this behavior in an earlier post.

So, what caused the crash?

No clue!

In order to find out what exactly went wrong, try adding a breakpoint to -[NSException raise]. Alternatively, you can modify the main function in main.m to be the following:

int main(int argc, char *argv[])
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int response;
    @try {
        response = UIApplicationMain(argc, argv, nil, nil);
    } @catch (NSException *e) {
        NSLog(@"%@: %@\nCall-stack:\n%@", [e name], [e reason], [e callStackSymbols]);
        response = 1;
    return response;

That will tell you in which method your program actually crashed.

share|improve this answer
add comment

Where is rocketTimer instantiated? You seem to have left that very important detail out. My guess is that rocketTimer isn't being correctly retained by your code and that is causing your crash when trying to access that object after it has been deallocated.

I'd suggest synthesizing your property and then using the built-in setting by setting self.rocketTimer when you initialize.


@interface FirstViewController : UIViewController {
    NSTimer *rocketTimer;
@property (nonatomic, retain) NSTimer *rocketTimer;
- (IBAction)Start;


@implementation FirstViewController
@synthesize rocketTimer;
// test of implementation
// ...
share|improve this answer
also, call [super dealloc] last in your dealloc. –  Lou Franco Mar 20 '11 at 2:47
"Where is rocketTimer instantiated? You seem to have left that very important detail out" No, he didn't. It's instantiated in the last line of the if-clause of his Start-method. –  danyowdee Mar 20 '11 at 20:23
@danyowdee Yep, missed that line. In any case, the timer isn't retained properly. –  raidfive Mar 21 '11 at 5:32
It doesn't need to: The timer is repeating and scheduled on the runloop — which retains the timer (see paragraph 2 sentence 2) until invalidate is called on it. –  danyowdee Mar 21 '11 at 8:19
add comment

If the problem is that it's not repeating, i'd let the timerLoop method check the value of totalSeconds before substracting. If it's 0, let it set it to 178 again.

If the problem lies somewhere else, please tell us where, and give us a little more information on what the problem is and what you've tried already next time.

share|improve this answer
add comment

Your Answer


