触摸屏幕后,nstimer停止

时间:2010-12-01 15:21:13

标签: iphone objective-c

我有一个定时器类,里面有一个nstimer,它将通知推送到uitableviewcontroller,并且通知对象(定时器的值)在uitableviewcell中受到影响。我的问题是当我触摸屏幕滚动,计时器停止,NSTimer不启动另一个线程?我如何解决这个问题。

我的timerClass

#import "timerEtape.h"
#import "FonctionUtile.h"
#import "Mission.h"

static timerEtape *sngTimerEtape = nil;

@implementation timerEtape

@synthesize repeatingTimerEtape;
@synthesize dateComp;
@synthesize questionCircuit;
@synthesize b_Pause;

+(timerEtape *) singletonTimer
{
    @synchronized(self){
        if (sngTimerEtape == nil ) 
        {
            sngTimerEtape = [[timerEtape alloc]init];
        }
    }

    return sngTimerEtape;
}

-(id)init
{
    self = [super init];

    if (self != nil) {
        dateComp = [[NSDateComponents alloc] init];
        b_Pause = FALSE;
    }

    return self;
}

- (void)startTimer {

    [repeatingTimerEtape invalidate];

    NSString * temps; 

    if (questionCircuit) {

        temps = [[Mission singletonMission].circuitTerrain valeurChampEtapeCircuitEnCours:@"et_temps_etape" :FALSE];
    }
    else {
        temps = [[Mission singletonMission].histoireTerrain valeurChampQuestion:@"hi_temps_etape" :FALSE];
    }

    if (!b_Pause) {
        [dateComp setHour:0];
        [dateComp setMinute:[[FonctionUtile gauche:temps :2] intValue]];
        [dateComp setSecond:[[FonctionUtile droite:temps :2] intValue]];
    }
    else {
        b_Pause = FALSE;
    }

    self.repeatingTimerEtape = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateLabelTimerEtape:) userInfo:nil repeats:YES];
}

-(void)pause
{
    self.b_Pause = TRUE;
    [repeatingTimerEtape invalidate];
}

-(void)updateLabelTimerEtape:(NSTimer*)theTimer
{

    if ([dateComp second] == 0) {

        if ([dateComp minute] == 0) {
            if ([dateComp hour] != 0) {
                [dateComp setHour:[dateComp hour] -1];
                [dateComp setMinute:59];
                [dateComp setSecond:59];
            }
            else {
                [repeatingTimerEtape invalidate];
                [delegate performSelector:touchAction];
            }

        }
        else {
            [dateComp setMinute:[dateComp minute] -1];
            [dateComp setSecond:59];
        }
    }
    else {
        [dateComp setSecond:[dateComp second] -1];
    }

    [[NSNotificationCenter defaultCenter] postNotificationName:@"rafraichirTimerEtape" object:[NSString stringWithFormat:@"%02d:%02d", [dateComp minute],[dateComp second]]];
}

-(void)setTarget:(id)target andAction:(SEL)action {
    delegate = target;
    touchAction = action;
}

-(void)dealloc
{
    [dateComp release];
    [repeatingTimerEtape release];

    [super dealloc];
}
@end

当我在uitableviewcontroller类中收到通知时

-(void)rafraichirTimerEtape:(NSNotification*)notification
{
    [tempsRestant release];
    tempsRestant = [[notification object]copy];

    [table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]].detailTextLabel.text = [notification object];
}   

感谢名单

1 个答案:

答案 0 :(得分:3)

之前我遇到过这个问题。实际上,NSTimer不会在另一个线程中运行,它总是在它启动的线程中运行。在iphone sdk中有一个runloop概念,你​​应该从here阅读它以了解计时器。在这个概念中,您将一些作业推送到runloop并且runloop按顺序实现它们。主线程始终是一个运行循环,ui作业在那里运行。因此,如果您在主线程中启动计时器,它将受到ui处理的影响。您应该启动一个新线程,将其配置为运行循环并在那里启动您的计时器。

编辑:以下是我发布的链接中的示例代码。 threadMain是线程启动的第一个函数。


- (void) threadMain
{
    NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];

    // Create and schedule the timer.
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self
                selector:@selector(doFireTimer:) userInfo:nil repeats:YES];

    NSInteger loopCount = 10;

    do
    {
        // Run the run loop 10 times to let the timer fire.
        [myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
        loopCount--;
    }
    while (loopCount);
}

如果你想让runloop无限运行,但是用条件终止它,请改用


BOOL shouldKeepRunning = YES;        // global

NSRunLoop *theRL = [NSRunLoop currentRunLoop];

[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
      selector:@selector(doFireTimer:) userInfo:nil repeats:YES];

while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode 
      beforeDate:[NSDate distantFuture]]);