【问题标题】:NSTimer, to retain or not to retainNSTimer,保留还是不保留
【发布时间】:2011-05-18 00:39:02
【问题描述】:

这件事让我困惑了一段时间。

我有一个 NSTimer,添加到 currentRunLoop,如果我不保留它,它就会崩溃。

NSTimer *timer = [[NSTimer timerWithTimeInterval:60.0 target:self selector:@selector(tryUnion:) userInfo:nil repeats:NO] retain];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

我已经读过我不需要保留它,因为 NSRunLoop 的 addTimer 就是这样做的。

稍后我将失效并释放(如果我不保留上面,我不释放下面 - 这是崩溃的情况):

- (void) tryUnion:(NSTimer*)aTimer {
[aTimer invalidate];
[aTimer release];
}

我的问题是 1)如果可以在没有保留/释放的情况下完成我所做的事情,我应该怎么写。 2)分析标记这个或“计时器”中对象的潜在泄漏。如这里所写,是否存在泄漏的可能性,或者只是分析器不够聪明,无法知道计时器调用的函数中有释放?

【问题讨论】:

  • 看起来我真正应该做的是:[NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(tryUnion:) userInfo:nil repeats:NO];没有运行循环调度,并且选择器中没有无效。是/没有人?我没有收到任何错误或分析器投诉。

标签: iphone nstimer


【解决方案1】:

规则是,如果你没有保留它,就不要释放它。 Here is a similar question which talks about that. 所以在你的示例代码中我建议不要保留它,不要释放它。

但这不是你的问题。您的问题是您创建了一个非重复计时器。您不需要使它们无效,它们在开火后会使它们自己无效。来自NSTimer docs

重复
如果是,计时器将 反复重新安排自己,直到 无效。如果否,计时器将 触发后失效。

因此,您既不应保留/释放该计时器,也不应使其无效。开火然后忘记。

顺便说一句,如果您使用scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:,那么将计时器添加到运行循环中也是为您完成的。所以你的整个事情就像:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(tryUnion:) userInfo:nil repeats:NO];

你的定时器函数不需要对aTimer做任何事情,只要做你的定时器应该做的事情;计时器将失效并释放,无需进一步干预。

【讨论】:

    【解决方案2】:

    在计时器上调用 invalidate 会释放它,因此您不需要另一个发布声明。请参阅文档here

    【讨论】:

    • 嗯,问题是因为我的计时器不重复,所以我不需要无效?因为如果我不保留(并且不释放),它会在运行选择器时崩溃(无效)
    • 经过测试,我发现我在 runloop 发布时遇到了同样的崩溃,而选择器中没有失效
    【解决方案3】:

    你说得对,NSTimer 不应该被保留。类方法+(NSTimer *)timerWithInterval 按照规则应该是autorelease 它的引用。

    但是 NSTimer 的 invalidate 消息将自己从 NSRunLoop 中删除,并释放了它的引用(当时只剩下一个)。您的第二个[aTimer release] 电话是导致崩溃的原因。

    【讨论】:

    • 不,如我的帖子中所述,如果我将计时器放入 *timer 并保留,我不会将释放放入回调中。如果没有保留和释放,它会失败并出现错误,跟踪到 >_CFRunLoopTimerDeallocate>CFRelease。
    猜你喜欢
    • 1970-01-01
    • 2011-11-10
    • 2012-02-14
    • 2011-08-16
    • 2019-08-03
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    相关资源
    最近更新 更多