2010-12-01 14 views
0

私は、nuitimerを内部に持つタイマークラスを持っていて、誰かがuitableviewcontrollerにプッシュ通知を送り、通知オブジェクト(タイマーの値)はuitableviewcellの影響を受けます。私の問題は、私がスクロールするために画面をタッチすると、タイマの停止、NSTimerは他のスレッドで起動しないのですか?どのように私はこの問題を解決することができます。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]; 
} 

ありがとう

答えて

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); 
} 

あなたは無限に実行されますが、条件とそれを終了するために実行ループしたい場合は、この代わりに


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]]); 
+0

ニースの答えを使用しています。小さなコードのサンプルをお探しですか? –

関連する問題