Dealloc 调用了两次并在 [super dealloc] 处崩溃

发布于 2024-12-04 20:22:40 字数 520 浏览 2 评论 0原文

---- 我自己解决了问题,我的评论中更新了信息 ----

我有一个视图控制器,它有一个定期的 NSTimer。当我删除视图控制器时,我调用计时器的无效:

- (void)dealloc
{
    NSLog(@"dealloc called");
    if ([myTimer isValid]) {
        [myTimer invalidate];
    }
    [super dealloc];
} 

我发现了一个意外的行为,[myTimer invalidate]将立即调用我的视图控制器的dealloc。这就是为什么我进行 isValid 检查以避免崩溃。但是 [super dealloc] 将被调用两次并使应用程序崩溃。

因此,我有两个问题:

  1. 使计时器无效的正确方法是什么?

  2. 为什么定时器的invalidate方法会调用视图控制器的dealloc方法?

谢谢利奥

---- question solved by myself, info updated in my comment ----

I have a view controller which has a periodic NSTimer. I call invalidate of the timer When I remove the view controller:

- (void)dealloc
{
    NSLog(@"dealloc called");
    if ([myTimer isValid]) {
        [myTimer invalidate];
    }
    [super dealloc];
} 

I discovered an unexpected behavior that the [myTimer invalidate] will immediately call my view controller's dealloc. That's why I put the isValid check to avoid crash. But the [super dealloc] will be called twice and crash the app.

Thus, I have two questions:

  1. What's the proper way to invalidate a timer?

  2. Why is the timer's invalidate method call the view controller's dealloc method?

Thanks

Leo

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

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

发布评论

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

评论(2

娇柔作态 2024-12-11 20:22:40

CocoaDev: NSTimer 中所述:

这里有一些可能对您使用 NSTimer 有所帮助的规则:

计时器保留目标和 userInfo 对象。

定时器在调度时由运行循环自动保留。

如果计时器未设置为重复,它将在触发时自动失效。

调用 invalidate 时,计时器会从运行循环中释放。

计时器在调用 invalidate 时释放 target 和 userInfo 对象。

换句话说,如果您释放重复计时器而不使其无效,它将继续重复,因为运行循环正在保留它。但是,如果您不想在应用程序退出之前停止计时器,或者计时器不重复,则可以在调度后释放它,而无需调用 invalidate。

As described at CocoaDev: NSTimer:

Here are a couple of rules that might help you with NSTimer:

A timer retains the target and userInfo objects.

A timer is automatically retained by the run loop when scheduling it.

If a timer is not set to repeat, it will automatically invalidate itself upon firing.

A timer is released from the run loop when calling invalidate.

A timer releases the target and userInfo objects when calling invalidate.

In other words, if you release a repeating timer without invalidating it, it will continue to repeate because the run loop is retaining it. However, if you don't want to stop the timer before the application quits, or if the timer is non-repeating, you can release it after scheduling it without calling invalidate.

暖伴 2024-12-11 20:22:40

这听起来像是一些奇怪的行为。是否有任何其他对象保留对视图控制器的引用?

如果没有,一旦定时器被移除,就有可能发生故障。从运行循环中释放后,视图控制器不再引用它(因此被释放)。

That sounds like some odd behaviour. Are there any other objects holding on to a reference to your view controller?

If not, there is a possibility that once the timer is removed & released from the run loop the view controller has nothing referencing it anymore (and so is deallocated).

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