2013-04-28 102 views
2

我用一個更新標籤的NSTimer編寫了一個計時器。問題是,在同一個viewcontroller我有一個可用視圖,當我向下滾動時,計時器不更新其值,因此用戶可以「作弊」停止計時器。更新標籤在後臺運行的計時器

我認爲這可以很容易地解決與CGD串行隊列,但我不知道如何做到這一點。

由於提前,

胡安

+1

重複:HTTP:/ /stackoverflow.com/questions/9090658/nstimer-not-fired-when-uiscrollview-event-occurs – Wain 2013-04-28 10:04:41

+0

你是對的,抱歉,但我沒有找到它 – 2013-04-28 12:17:01

回答

2

,首先要記住,你不能在任何其他線程比主線程中執行UI的變化。話雖如此,您需要NSTimer才能在主隊列中啓動,否則在更改UILabel時程序會崩潰。看看這個鏈接http://bynomial.com/blog/?p=67這一個http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html

據我所知,如果您安排的計時器在爲NSRunLoopCommonModes它會忽略事件的更新,並觸發計時器僅僅指剛你想要的:

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 
              target:self 
             selector:@selector(timerDidTick:) 
             userInfo:nil repeats:YES]; 
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

-(void) timerDidTick:(NSTimer*) theTimer{ 
    [[self myLabel] setText:@"Timer ticked!"]; 
} 
0

如果你在主線程中運行計時器的時候遇到同樣的問題,那麼你的tableview也會停止計時器。解決方案是,你在主線程在後臺運行,並更新GUI計時器

UIApplication *app = [UIApplication sharedApplication]; 
__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
}]; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    //run function methodRunAfterBackground 
    updateTimer1=[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateGUIAudioPlayer) userInfo:nil repeats:YES]; 
    [[NSRunLoop currentRunLoop] addTimer:updateTimer1 forMode:NSDefaultRunLoopMode]; 
    [[NSRunLoop currentRunLoop] run]; 
}); 

    -(void)updateGUIAudioPlayer { 
dispatch_async(dispatch_get_main_queue(), ^{ 
    self.label.text = @"your text"; 
}); 

    //but if you want to stop timer by himself than use main thread too like that 

    dispatch_async(dispatch_get_main_queue(), ^{ 
      [updateTimer1 invalidate]; 
     });} 
0
-(void) timerDidTick:(NSTimer*) theTimer{ 
     _currentNumber =_currentNumber+1; 
     //check if current number is bigger than the contents of the word array 
     if (_currentNumber <=wordArray.count-1) { 
      NSLog(@"_currentNumber @%i wordArray @%i",_currentNumber,wordArray.count); 
      _RandomLoadingText.text = @"Timer" ; 
      [self changeTextInRandomLoadingLabel:_currentNumber]; 
     } 

     else if (_currentNumber >=wordArray.count-1) 
     { 
      NSLog(@"reached end of array"); 
      [timer invalidate]; 
     } 
    } 

-(void)changeTextInRandomLoadingLabel:(int)myInt 
{ 
    _RandomLoadingText.text = [wordArray objectAtIndex:myInt]; 
} 

// --------- 視圖做負載

_RandomLoadingText.text = @"Test"; 
    _currentNumber =0; 
    timer = [NSTimer timerWithTimeInterval:1.0 
              target:self 
              selector:@selector(timerDidTick:) 
              userInfo:nil repeats:YES]; 
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];