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

时间:2011-09-20 10:56:25

标签: iphone nstimer dealloc invalidation nsrunloop

我从应用程序中的服务器获取带有secondsToEnd值的信息,并在收到此信息后启动计数器。

我的项目包含一个滚动视图,所以为了绕过锁定我的计时器由于滚动我将以下列方式将计时器添加到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];
}

在start方法中检查无效的原因是因为在secondsToEnd值达到0之后,我收到一个新的,然后再次调用startTimer。

在我的dealloc方法中,我有这个:

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

但它没有失效?我做错了什么?

2 个答案:

答案 0 :(得分:3)

这些逗号分隔的语句执行的顺序是什么?如果在调用invalidate或调用release时_timer为nil会发生什么?

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

试试这个,不需要检查_timer是否已经为零。如果它为零,则方法调用不执行任何操作。

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

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

答案 1 :(得分:1)

您应先致电[timer release]然后再timer = nil。在dealloc方法中也是如此。如果外部对象在自动释放池中,则可能无法立即调用dealloc方法。在这些情况下,系统决定最终丢弃对象时调用它。所以可能需要一些时间(如果设置断点)。

BTW我建议避免使用逗号语法,而是在花括号中使用块。它更容易阅读。