【发布时间】:2010-09-15 15:47:17
【问题描述】:
iPhone 应用程序中的奇怪问题。
我的应用程序的主视图是 View A,它是一个选项卡控制器。特别是一个选项卡被设置为加载视图 B。当您单击按钮时,视图 B 以模态方式显示视图 C。视图 C 又具有一个按钮,当按下该按钮时,会向其委托(视图 B 的视图控制器)发送消息,然后代理关闭视图 C。
现在,我的理解是视图 A 始终持有对视图 B 的引用。是吗?
顺序如下:
- 选择选项卡以显示视图 B。
- 按下按钮显示视图 C(模态)。
- 按下按钮关闭 - 视图 C 发送消息,视图 B 的控制器执行关闭。现在显示视图 B。
- 重复步骤 2-3 两次。
- 视图 B 的视图控制器解除分配(我在 dealloc 中有一个 NSLog,所以我知道这正在发生)。视图仍然显示。
- 按下按钮显示视图C,得到“EXC_BAD_ACCESS”,因为视图B的视图控制器已被释放,所以按钮的“点击”消息无处可去。
在任何时候都不会出现内存警告 - 我已将 NSLog 放入以确保它。 View A 和 View B 都是在 Interface Builder 中构建的,而不是在代码中,而且我绝对没有编写过会调用 View B 的 dealloc 方法的代码。
这总是发生在恰好重复 3 次之后。
作为参考,按钮本身是在视图 B 的 viewWillAppear 方法中以编程方式构造的。这是sn-p:
// 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];
所以按钮应该向视图 B 的视图控制器发送“buttonClicked”消息。前三次效果很好,在视图控制器神秘地释放后停止工作。
视图 B 应该永远解除分配,因为它是显示在应用程序标签栏中的顶级视图。
任何想法我可以从哪里开始解决这个问题?
编辑:有趣的琐事。我在视图 B 的 viewDidLoad 中添加了一个 [self retain],这应该会增加对象的保留计数。确实如此:在获得 EXC_BAD_ACCESS 之前,我现在可以执行上述过程四次。我正在使用 NSZombiesEnabled 运行,所以我知道视图 B 的控制器正在被释放。我只需要弄清楚它的保留计数在哪里减少,因为我实际上并没有编写任何这样做的代码。
我知道视图 A 应该增加视图 B 的保留计数;当视图 B 随后模态显示视图 C 时,不应该减少计数,不是吗?
【问题讨论】:
-
您是否在这两个视图中正确发布了所有其他内容?另外,您能否发布一些与您如何创建/关闭这些视图相关的代码?
标签: ios memory-management