iOS UIViewController解除分配?

时间:2010-09-15 15:47:17

标签: ios memory-management

iPhone应用中的奇怪问题。

我的应用程序的主视图是View A,它是一个选项卡控制器。特别是一个选项卡设置为加载视图B.视图B,当您单击按钮时,模态显示视图C.视图C依次有一个按钮,按下该按钮时,会向其代理发送消息(视图B的视图控制器),然后代表驳回了View C.

现在,我的理解是View A总是持有对View B的引用。是吗?

以下是序列:

  1. 选择标签以显示视图B.
  2. 按按钮显示视图C(模态)。
  3. 按按钮关闭 - 查看C发送消息,视图B的控制器解除消息。现在显示视图B.
  4. 重复步骤2-3 TWICE MORE。
  5. 查看B的视图控制器解除分配(我在dealloc中有一个NSLog,所以我知道这种情况正在发生)。视图仍然显示。
  6. 按按钮显示视图C,获取“EXC_BAD_ACCESS”,因为视图B的视图控制器已被取消分配,因此按钮的“点击”消息无处可去。
  7. 任何时候都没有发生内存警告 - 我已经安装了NSLog以确保它。视图A和视图B都是在Interface Builder中构建的,而不是在代码中构建的,并且绝对没有我编写的代码将调用View B的dealloc方法。

    这经常在完全重复三次之后发生。

    作为参考,按钮本身是在View B的viewWillAppear方法中以编程方式构造的。这是片段:

        // create button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(column*100+24, row*80+10, 64, 64);
        [button setImage:thumb forState:UIControlStateNormal];
        [button addTarget:self 
                        action:@selector(buttonClicked:) 
            forControlEvents:UIControlEventTouchUpInside];
    

    因此该按钮应该向View B的视图控制器发送“buttonClicked”消息。前三次工作得很好,在视图控制器神秘地解除分配后停止工作。

    视图B应从不取消分配,因为它是应用程序标签栏中显示的顶级视图。

    无论如何我都可以开始对此进行故障排除?

    编辑:有趣的琐事。我在View B的viewDidLoad中添加了一个[self retain],它应该增加对象的保留计数。它确实:我现在可以在获得EXC_BAD_ACCESS之前完成上述过程四次。我正在运行NSZombiesEnabled,所以我知道它是View B的控制器,它已被取消分配。我只需要弄清楚它的保留计数正在递减,因为我实际上没有编写任何代码。

    我知道View A应该增加View B的保留计数;当View B随后以模态方式显示View C时,不应该减少计数,是吗?

1 个答案:

答案 0 :(得分:1)

如果不看代码就不能说,但如果我猜:

  1. 在第三步中,当您解除视图控制器C时,不会释放视图控制器C,而是意外释放B.错误显示需要一段时间,因为B在其他对象上有几个保留。但是,每次释放C时,都会减少释放次数,直至达到零。
  2. 您有一个自定义访问者,例如C的委托属性,在访问时向B发送一个版本。与(1)相同的模式。
  3. 我建议您在发布时进行项目搜索并检查所有版本以查看是否有B.在标准设置中应该没有明确的B版本。

    您还可以覆盖B的release方法,以便在发布时记录(不要忘记调用超级),它会在发布时向您显示,这样可以让您了解它们发生的位置。