(NSTimer) creating a Timer Countdown

2019-02-17 08:10发布

问题:

I am trying to create a simple Countdown Timer so that when a player enters my game the timer begins from 60 down to 0. It seems simple but I am getting confused at how I write this.

So far I have created a method within my GameController.m that looks like this:

-(int)countDownTimer:(NSTimer *)timer {
    [NSTimer scheduledTimerWithTimeInterval:-1
                                 invocation:NULL
                                    repeats:YES];
    reduceCountdown = -1;
    int countdown = [[timer userInfo] reduceCountdown];
    if (countdown <= 0) {
        [timer invalidate];
    }
    return time;
}

At the start of the game I initialise the integer Time at 60. The label is then being set within ViewController. But at the moment when I compile the code it just shows the label at 60 and doesn't decrement at all.

Any help would be greatly appreciated - I am new to Objective-C.


EDIT

With some assistance from I have now separated the code into 2 separate methods. The code now looks like this:

-(void)countDown:(NSTimer *)timer {
    if (--time == 0) {
        [timer invalidate];
        NSLog(@"It's working!!!");
    }
}

-(void)countDownTimer:(NSTimer *)timer {
    NSLog(@"Hello");
    [NSTimer scheduledTimerWithTimeInterval:1
                                      target:self
                             selector:@selector(countDown:)
                                      userInfo:nil
                                      repeats:YES];
}

HOWEVER, the code is still not running properly and when I call the method [game countDownTimer] from my View Controller it breaks saying: "unrecognized selector sent to instance". Can anybody explain what is wrong here?

回答1:

Several things are wrong with your code:

  • You are passing a wrong parameter for the time interval - negative numbers are interpreted as the 0.1 ms
  • You are calling the wrong overload - you are expected to pass an invocation object, yet you are passing a NULL
  • You put the code that you want executed on timer together with timer initialization - the code that needs to be executed on timer should go into a separate method.

You should call the overload that takes a selector, and pass 1 for the interval, rather than -1.

Declare NSTimer *timer and int remainingCounts, then add

timer = [NSTimer scheduledTimerWithTimeInterval:1
                                         target:self
                                       selector:@selector(countDown)
                                       userInfo:nil
                                        repeats:YES];
remainingCounts = 60;

to the place where you want to start the countdown. Then add the countDown method itself:

-(void)countDown {
    if (--remainingCounts == 0) {
        [timer invalidate];
    }
}


回答2:

Try this

- (void)startCountdown
{
    _counter = 60;

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1
                                                      target:self
                                                    selector:@selector(countdownTimer:)
                                                    userInfo:nil
                                                     repeats:YES];
}

- (void)countdownTimer:(NSTimer *)timer
{
    _counter--;
    if (_counter <= 0) { 
        [timer invalidate];
        //  Here the counter is 0 and you can take call another method to take action
        [self handleCountdownFinished];
   }
}


回答3:

From the question you posed.you can achieve that by invoking a function for every 1 sec and handle the decrement logic in that.

Snippet:-

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 1.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:YES];
(void)onTick
{
   //do what ever you want
   NSLog(@"i am called for every 1 sec");
//invalidate after 60 sec [timer invalidate];
}