我正在设置一个计时器,以13分钟的间隔开火。但计时器似乎是不定期地被解雇。这是一个间歇性的问题。一些用户报告了这个问题,我无法重现这个问题。
- (void)resetIdleTimer
{
if (_idleTimer)
{
[_idleTimer invalidate];
[_idleTimer release];
_idleTimer = nil;
}
_idleTimer = [[NSTimer scheduledTimerWithTimeInterval:13*60.0
target:self
selector:@selector(idleTimerExceeded)
userInfo:nil
repeats:NO] retain];
}
- (void)idleTimerExceeded
{
// do some processing
[_idleTimer release];
_idleTimer = nil;
}
根据某些条件,计时器将被重置(resetIdleTimer),但无论如何都会重置计时器13分钟。
当我查看代码时,我只能看到没有将timer参数传递给选择器的问题。我不确定这是否是这个问题的原因?有没有人遇到过这种奇怪的事情? (我将如何更新代码以将计时器作为参数)。 一位用户报告说它刚刚发生4分钟后发生。
答案 0 :(得分:1)
让我们确认一件事,不将timer参数传递给选择器不会引起任何问题。
这是更新的代码,可以正常使用
@property(nonatomic,strong)NSTimer *myTimer;
或
@property(nonatomic,retain)NSTimer *myTimer;
<强>方法强>
- (void)resetIdleTimer
{
if ([self.myTimer isValid])
[self.myTimer invalidate];
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:13*60.0
target:self
selector:@selector(idleTimerExceeded)
userInfo:nil
repeats:NO];
}
- (void)idleTimerExceeded
{
NSLog(@"tiggered");
}
答案 1 :(得分:0)
我没有在你的代码中发现任何错误,唯一的想法是用户进入你的类创建一个实例,让我们称之为实例“A”,然后启动计时器,然后在13分钟之前退出你的班级,然后再次输入新的实例“B”,新的计时器开始......
此时用户希望您的计时器方法在13分钟后触发...但是“A”的计时器仍处于待处理状态(因为您关闭课程的方式可能有错误)并执行...
您可以尝试添加一些日志并尝试按照我的说法进行操作,并检查所有日志(特别是如果您输入dealloc,并且idleTimerExceeded打印实例中的日志等于resetIdleTimer中打印的最后一个实例):< / p>
-(void)resetIdleTimer {
if (_idleTimer)
{
[_idleTimer invalidate];
[_idleTimer release];
_idleTimer = nil;
}
NSLog(@"...resetIdleTimer: instance: %p", self);
_idleTimer = [[NSTimer scheduledTimerWithTimeInterval:13*60.0
target:self
selector:@selector(idleTimerExceeded)
userInfo:nil
repeats:NO] retain];
NSLog(@"...resetIdleTimer: _idleTimer: %p", _idleTimer);
}
- (void)idleTimerExceeded
{
// do some processing
NSLog(@"...idleTimerExceeded: instance: %p", self);
NSLog(@"...idleTimerExceeded: _idleTimer: %p", _idleTimer);
[_idleTimer release];
_idleTimer = nil;
}
-(void) dealloc
{
NSLog(@"...dealloc: instance: %p", self);
[super dealloc];
}
只是一个想法......但你可能已经忘记了计时器保留了target:
参数中传递的实例(你传递了“self”,所以保留了你的类实例),所以常见的错误就是忘记了关闭类实例时关闭计时器。
正确的方法应该是:
-a root class(AAA)使用计时器实例化您的类(BBB) -BBB启动它的计时器 -AAA想要dealloc / resetIdleTimer类BBB:在释放之前它必须停止/使BBB.timer无效(如果没有定时器保留BBB,并且在定时器触发/执行其方法之前不会释放BBB)
所以,如果是你的情况......添加一个可以从类AAA中调用的方法来停止/使计时器无效,例如:
-(void)stopTimer{
if (_idleTimer)
{
[_idleTimer invalidate];
[_idleTimer release];
_idleTimer = nil;
}
}
答案 2 :(得分:0)
如果您希望计时器在13分钟内完成,可能会有所帮助: