2014-02-07 106 views
0

我以前有一个NSTimer这是工作正常。我为runloop添加了另一个NSTimer,因为现在我需要在延迟后重复调用两个函数。两种功能都有不同的延迟。我的代码如下。第二个NSTimer不工作?

self.now = [NSDate date] ; 
    self.timer = [[NSTimer alloc] initWithFireDate:self.now 
              interval:500 
              target:self 
              selector:@selector(Func1) 
              userInfo:nil 
              repeats:YES] ; 

    self.runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 
    [self.runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10000]]; 


    //Second timer start here.its not working.The function 'func2' is not getting called 

    self.now = [NSDate date] ; 
    self.timer = [[NSTimer alloc] initWithFireDate:self.now 
              interval:60 
              target:self 
              selector:@selector(Func2) 
              userInfo:nil 
              repeats:YES] ; 

    self.runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 
    [self.runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10000]]; 

第一NSTimer仍在工作,但第二NSTimer不起作用。

回答

2

你必须声明NSTimer的第二个属性。目前,你在你的界面类似物这样

self.timer = [[NSTimer alloc] initWithFireDate:self.now 
             interval:60 
             target:self 
             selector:@selector(Func2) 
             userInfo:nil 
             repeats:YES] ; 

申报定时器到你的计时器声明和使用self.timer2存储第二拍时覆盖你的第一个计时器。

+1

如果在进行Volker建议的修复后仍然看到问题,我会查看您的runloop调用。这看起来不正确。您应该设置两个定时器,将它们添加到runloop,就是这样(如果这是主线程)。如果不是,你必须自己关闭运行循环,我认为它应该在一个while循环中完成。 –

+0

@Volker它仍然没有工作 – zzzzz

+0

请参阅Rob的解答您的代码中的另一个问题的答案 – Volker

3

虽然覆盖属性并不好(它不会影响定时器的运行能力,但它意味着当您设置第二个定时器时,您将丢弃对第一个定时器的引用定时器,因此你失去了第一个定时器的能力,如果你需要这样做的话),关键问题是你打电话给runUntilDate。没有必要这样做,并且第一个runUntilDate正在阻止发生第二个定时器的创建,因为viewDidLoad不会超出第一个runUntilDate呼叫。

所以删除拨打runUntilDate这两个电话和两个计时器将正常工作。如果要保留对两个定时器的引用,请使用不同的属性保存对两个定时器的引用,以便在不再需要它们的情况下单独使用这两个定时器。 (而且,重要的是你invalidate他们当你不再需要它们,因为它们保持较强的参考self,这意味着你有一个“强有力的参考周期”。)


你可以简化代码示例:

NSDate *date = [NSDate date]; 

self.timer1 = [[NSTimer alloc] initWithFireDate:date 
             interval:500 
             target:self 
             selector:@selector(method1:) 
             userInfo:nil 
             repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer:self.timer1 forMode:NSRunLoopCommonModes]; 

self.timer2 = [[NSTimer alloc] initWithFireDate:date 
             interval:60 
             target:self 
             selector:@selector(method2:) 
             userInfo:nil 
             repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer:self.timer2 forMode:NSRunLoopCommonModes]; 

或者,除非你真的需要NSRunLoopCommonModes,你可能只是做:

self.timer1 = [NSTimer scheduledTimerWithTimeInterval:500 
               target:self 
              selector:@selector(method1:) 
              userInfo:nil 
               repeats:YES]; 

self.timer2 = [NSTimer scheduledTimerWithTimeInterval:60 
               target:self 
              selector:@selector(method2:) 
              userInfo:nil 
               repeats:YES]; 

,并注意,我用的方法用参数(因此与选择的结肠):

- (void)method1:(NSTimer *)timer 
{ 
    // do whatever 
} 

- (void)method2:(NSTimer *)timer 
{ 
    // do whatever 
} 
+0

我需要永远运行两个计时器,并且需要重复运行它们。如何在没有rununtildate的情况下执行此操作? – zzzzz

+0

@Worker只需创建定时器并删除'runUntilDate',它们都将永远运行(或者,更准确地说,直到您为各个定时器调用'invalidate')。 – Rob

+0

这不起作用。该应用程序崩溃。 – zzzzz

0

其实runUntilDate将引起该应用继续运行计时器,并且在此之后,语句将不会被执行。试试这个:即使你使用了两个定时器相同timer变量

self.now = [NSDate date] ; 
self.timer = [[NSTimer alloc] initWithFireDate:self.now 
             interval:500 
             target:self 
             selector:@selector(Func1) 
             userInfo:nil 
             repeats:YES] ; 

self.runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 


//Second timer start here.its not working.The function 'func2' is not getting called 

self.now = [NSDate date] ; 
self.timer = [[NSTimer alloc] initWithFireDate:self.now 
             interval:60 
             target:self 
             selector:@selector(Func2) 
             userInfo:nil 
             repeats:YES] ; 

self.runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode]; 

,它会工作。但正如在其他答案中指出的那样,你失去了使第一个计时器无效的能力。只需在两个地方发表runUntilDate声明即可。

0

为您的计时器声明第二个属性不是解决方案。您只需使旧计时器失效并在主线程上分配新计时器,它就会工作!试试这个:

dispatch_async(dispatch_get_main_queue(), ^{ 
    _timer = [NSTimer scheduledTimerWithTimeInterval:interval 
                target:self 
                selector:@selector(function:) 
                userInfo:nil 
                repeats:YES]; 
    [_timer fire]; 
    });