更新标签在后台运行的计时器

我已经用一个更新标签的NSTimer编码了一个计时器。 问题是,在同一个viewcontroller我有一个uitableview,当我向下滚动,定时器不更新其值,所以用户可以“作弊”停止计时器。

我认为这可以很容易地解决与CGD串行队列,但我不知道如何做到这一点。

提前致谢,

胡安

首先请记住,除了主线程以外的任何线程都不能执行UI更改。 话虽如此,您需要在主队列中启动NSTimer ,否则在更改UILabel时程序将崩溃。 看看这个链接http://bynomial.com/blog/?p=67和这一个http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class/参考/的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!"]; } 

如果你在主线程中运行定时器的时候遇到了同样的问题,那么你的tableview也会停止计时器。 解决scheme是你在后台运行计时器,并在主线程中更新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]; });} 
 -(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];