开发者

how to unschedule NSTimer in objective-c

I am using nested NSTimer in an application. I have two issues here.

  1. How to re-initiate time counter in this function - (void)updateLeftTime:(NSTimer *)theTimer
  2. How to kill previous timer because - (void)updateLevel:(NSTimer *)theTimer is also calling by timer.

- (void)viewDidLoad {
    [super viewDidLoad];

    tmLevel=[NSTimer scheduledTimerWithTimeInterval:20.0f target:self selector:@selector(updateLevel:) userInfo:nil repeats:YES];

    tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES];
}

- (void)updateLevel:(NSTimer *)theTimer {
    static int count = 1;
    count += 1;

    lblLevel.text = [NSString stringWithFormat:@"%d", count];

    tfLeftTime.text=[NSString stringWithFormat:@"%d",ANSWER_TIME];

    tmLeftTime=[[NSTimer alloc] init];
    tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES];
    [self playMusic];

}
- (void)updateLeftTime:(NSTimer *)theTimer 开发者_如何学Go{
    static int timeCounter=1;
    timeCounter+=1;
    tfLeftTime.text=[NSString stringWithFormat:@"%d", (ANSWER_TIME-timeCounter)];
}


  • Use [tmLevel invalidate] to cancel schedule of a timer.
  • Don't forget to set tmLevel=nil immediately after (to avoid using the variable after the timer has been unscheduled and released by the Runloop)
  • Don't forget to invalidate the tmLevel timer before loosing the reference to it, namely call [tmLevel invalidate] also before assigning a new NSTimer to the tmLevel variable (or else the previous timer will continue to run in addition to the new one)

Note also that in your code you have useless allocations that are moreover creating a leak:

tmLeftTime=[[NSTimer alloc] init];
tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES];

here you allocate an NSTimer instance, store this instance in tmLeftTime... and then immediately forget about this created instance to replace it with another one, created using [NSTimer scheduledTimerWithTimeInterval:...]! Therefore, the NSTimer created using [[NSTimer alloc] init] is lost, and is creating a leak (as it will never be released).

Your first line is totally useless, it's kinda like you were doing

int x = 5;
x = 12; // of course the value "5" is lost, replaced by the new value


add the following lines when u want to reset the timer

[tmLeftTime invalidate]; 
tmLeftTime = nil;

you can also use

if ([tmLeftTime isValid]){
  // the timer is valid and running, how about invalidating it
  [tmLeftTime invalidate]; 
    tmLeftTime = nil;
}


How about using only one timer instead of 3?

- (void)viewDidLoad {
    [super viewDidLoad];

    tmLeftTime=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES];
}

- (void)updateLevel {
    static int count = 1;
    count += 1;

    lblLevel.text = [NSString stringWithFormat:@"%d", count];

    tfLeftTime.text=[NSString stringWithFormat:@"%d",ANSWER_TIME];

    [self playMusic];

}
- (void)updateLeftTime:(NSTimer *)theTimer {
    static int timeCounter=1;
    timeCounter+=1;
    tfLeftTime.text=[NSString stringWithFormat:@"%d", (ANSWER_TIME-timeCounter)];
    if (timeCounter >= ANSWER_TIME) {
        timeCounter = 0;
        [self updateLevel];
    }
}


Invalidate your timer with the invalidate method in your updateLevel: method and re-schedule the same timer.

[tmLevel invalidate];
tmLevel = [NSTimer scheduledTimerWithTimeInterval:20.0f target:self selector:@selector(updateLevel:) userInfo:nil repeats:YES];

And if you wanna call the updateTimeLeft: method you don't need to alloc another timer, that's a big leak since you're never releasing those references.

tmLeftTime = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES];

And in your updateTimeLeft: just re-schedule the timer's method and set a condition where it should stop.

tmLeftTime = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateLeftTime:) userInfo:nil repeats:YES];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜