【问题标题】:Dealloc called twice and crash at [super dealloc]Dealloc 调用了两次并在 [super dealloc] 处崩溃
【发布时间】:2011-11-17 18:40:20
【问题描述】:

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

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

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

我发现 [myTimer invalidate] 将立即调用我的视图控制器的 dealloc 的意外行为。这就是我放置 isValid 检查以避免崩溃的原因。但是 [super dealloc] 将被调用两次并导致应用程序崩溃。

因此,我有两个问题:

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

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

谢谢

狮子座

【问题讨论】:

  • 您应该在 viewDidUnload 下放置 invalidate 语句以避免崩溃。
  • 这听起来有些奇怪。是否有任何其他对象保留对您的视图控制器的引用 - 如果没有,是否有可能一旦定时器从NSRunLoop 删除并释放,视图控制器就没有任何引用它了(因此被释放)?
  • @studev,你是对的。我只是认为视图控制器在这段代码之外被错误地释放了。计时器的无效将释放目标,但不应调用目标的 dealloc。相反,保留计数应该从 2 减少到 1。因为当我安排计时器时,计时器保留了目标。
  • 好的,很高兴听到 - 我会添加我的评论作为答案。

标签: iphone objective-c cocoa-touch ipad nstimer


【解决方案1】:

CocoaDev: NSTimer所述:

以下是一些可能对您使用 NSTimer 有所帮助的规则:

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

运行循环在调度时会自动保留一个计时器。

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

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

当调用 invalidate 时,计时器会释放目标和 userInfo 对象。

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

【讨论】:

  • 如果您复制粘贴非您自己编写的内容,请注明原文出处,并明确该文字不是您的。抄袭不被接受,可能被认为是非法的。
  • 对不起......
【解决方案2】:

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

如果没有,有可能一旦定时器从运行循环中移除并释放,视图控制器就没有任何引用它了(因此被释放)。

【讨论】:

    猜你喜欢
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多