我以前只有一个NSTimer
工作正常。我已经在我的runloop中添加了另一个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
无效。
答案 0 :(得分:3)
虽然你覆盖你的属性并不好(它不会影响计时器的运行能力,但它只是意味着当你设置第二个计时器时你丢弃对第一个计时器的引用,因此你失去了invalidate
第一个计时器的能力,如果你需要这样做,关键问题是你正在调用runUntilDate
。没有必要这样做,第一个runUntilDate
阻止了第二个计时器的创建,因为viewDidLoad
将不会超出第一个runUntilDate
电话。
因此,删除对runUntilDate
的两次调用,两个计时器都能正常工作。如果要保留对两个计时器的引用,请使用不同的属性来保存对两个计时器的引用,以便在不再需要它们时可以单独invalidate
它们。 (当你不再需要它们时,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
}
答案 1 :(得分:2)
您必须声明NSTimer的第二个属性。目前,在执行此操作时,您将覆盖第一个计时器
self.timer = [[NSTimer alloc] initWithFireDate:self.now
interval:60
target:self
selector:@selector(Func2)
userInfo:nil
repeats:YES] ;
在您的界面中声明timer2与您的计时器声明类似,并使用self.timer2存储第二个计时器。
答案 2 :(得分:0)
实际上runUntilDate
会导致应用程序继续运行计时器,之后的语句将不会被执行。试试这个:
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];
即使您对两个计时器使用相同的timer
变量,它也会起作用。但正如其他答案所指出的那样,你失去了使第一个计时器无效的能力。只需注释掉这两个地方的runUntilDate
语句。
答案 3 :(得分:0)
为您的计时器声明第二个属性不是解决方案。你只需要使旧计时器无效并在主线程上分配新的计时器就可以了!试试这个:
dispatch_async(dispatch_get_main_queue(), ^{
_timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(function:)
userInfo:nil
repeats:YES];
[_timer fire];
});