2013-04-28 105 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];