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

发布于 2024-12-05 15:10:34 字数 1228 浏览 3 评论 0原文

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

我的项目包含一个滚动视图,因此为了避免因滚动而锁定计时器,我通过以下方式将计时器添加到 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];

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

I get information from a server in my app with a secondsToEnd value and I start a counter after I've received this information.

My project contains a scrollview, so to get around locking my timer due to scrolling around I add the timer to the NSRunLoop in the following way:

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

I made a NSTimer property called, how original, timer and this is the whole snippet of my startTimer function:

- (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];
}

The reason for the check to invalidate in the start method is because after the secondsToEnd value hits 0, I receive a new one and I call startTimer again.

And in my dealloc method I have this:

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

But it doesn't get invalidated? What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆梦 2024-12-12 15:10:34

这些逗号分隔的语句以什么顺序执行?当你调用 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,该方法结束后它的存储就消失了。

What order do these comma separated statements execute in? What happens if _timer is nil when you call invalidate or when you call release?

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

Try this instead, there is no need to check whether _timer is already nil. If it was nil then the method call does nothing.

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

In the dealloc method there is no need to set _timer = nil, its storage is gone after this method ends.

迷离° 2024-12-12 15:10:34

您应该首先调用[timer release],然后调用timer = nil。与 dealloc 方法相同。如果外部对象位于 autrelease 池中,则 dealloc 方法可能不会立即被调用。在这些情况下,当系统决定最终删除您的对象时会调用它。所以可能需要一些时间(如果你设置了断点)。

顺便说一句,我建议避免使用逗号语法并使用大括号内的块。它更容易阅读。

You should first call [timer release] and then timer = nil. Same in dealloc method. The dealloc method might no get called immediately if outer objects are in autrelease pools. In these cases it is called when the system decides to drop your object finally. So it may take some time (if you set a breakpoint).

BTW I would suggest to avoid comma syntax and use blocks within curly braces instead. It's far more easier to read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文