如何在NSRunLoop中正确地使我的计时器无效

问题描述:

我从我的应用程序中的服务器获取信息,具有secondsToEnd值,并在收到此信息后启动计数器。如何在NSRunLoop中正确地使我的计时器无效

我的项目包含一个滚动视图,所以避过*我的计时器由于滚动我周围的计时器添加到NSRunLoop下列方式:

[[NSRunLoop currentRunLoop] addTimer:timer 
          forMode:NSRunLoopCommonModes]; 

我做了一个的NSTimer属性调用,怎么原来,计时器,这是我startTimer所功能的整个片段:

- (void)startTimer 
{ 
    if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release]; 

    NSTimer * timer = [[NSTimer alloc] initWithFireDate:[NSDate date] 
               interval:1.0 
               target:self 
               selector:@selector(timer:) 
               userInfo:nil 
               repeats:YES]; 

    [[NSRunLoop currentRunLoop] addTimer:timer 
           forMode:NSRunLoopCommonModes]; 

    [self setTimer:timer]; 
    [timer release]; 
} 

的原因检查在启动方法失效是因为secondsToEnd值命中0后,我收到一个新的,我再打电话startTimer所。

而在我的dealloc方法我有这样的:

if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release]; 

但它不会失效?我究竟做错了什么?

+0

你的dealloc被调用了吗?验证一个断点或在那里添加NSLog。 – progrmr

您应该先致电[timer release],然后拨打timer = nil。同dealloc方法。如果外部对象位于自动发布池中,则可能不会立即调用dealloc方法。在这些情况下,系统决定最终放弃对象时调用它。所以可能需要一些时间(如果你设置了一个断点)。

顺便说一句我建议避免使用逗号语法,而应在花括号内使用块。阅读起来要容易得多。

+0

+1,以避免使用comman语法,并使用{}代替。 – progrmr

+0

我想我曾经用过一些块,并带有一些动画代码。在这种情况下你会如何使用它?释放和零的开关没有修复它顺便:( –

+0

我认为我误读你有关块的评论,你的意思是这样的:NSTimer * timer = {[NSTimer alloc] initWithFireDate:[NSDate date] interval :1.0 目标:自 选择器:@selector(定时器:) USERINFO:无 重复:YES] }; –

这些逗号分隔语句执行的顺序是什么?如果_timer在您致电无效或致电发布时为零,会发生什么情况?

if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release]; 

试试这个,而不需要检查_timer是否已经为零。如果它是零,那么方法调用什么都不做。

if ([_timer isValid]) { 
    [_timer invalidate]; 
} 
[_timer release]; 

在dealloc方法中,不需要设置_timer = nil,在此方法结束后,它的存储空间不见了。

+0

我试过了,但没有运气。它可以用除dealloc之外的任何方法工作,但不知何故,它感觉有些第二个计数器潜入某处。但我更改了我的代码以将计时器添加到可变数组中,并且计数始终为1. –

+0

可变数组将保留计时器,除非释放数组,否则它将永远不会被释放。 – progrmr

+0

订单+1 - 好主意 – Kay