【发布时间】:2011-01-07 14:34:55
【问题描述】:
我有一个 UITableViewController,它有一个名为 errorView 的 UIView*,用于在方法无法加载 Web 数据时将错误消息覆盖在表格视图上。
在 init 方法中,errorView 设置为 nil(在调试器中为 0x0)。
在加载方法中,在 init 结束时调用,如果点击了“刷新”UIButton(在 errorView 上),errorView 与 nil 进行比较,如果它不是 nil,则从 superview 中删除并释放(仍然显示 0x0在调试器中)。
在dealloc方法中,释放前做同样的检查;但由于某种原因,即使尚未分配变量(调试器中为 0xc000),该变量也永远不会为零,因为从未调用过数据失败方法。然后应用程序崩溃,因为它试图释放一个空指针,即 != nil。
例子:
-(id)init {
errorView = nil;
[self Load];
}
-(void)Load {
if(errorView != nil) {
[errorView removeFromSuperView];
[errorView release];
errorView = nil;
}
//Attempt to load data from web
}
-(void)dataFailedToLoad (e.g. UIWebView didFailLoadWithError) {
errorView = [[UIView alloc] initWithFrame, etc];
[self.tableView addSubview:errorView];
}
-(void)dealloc {
if(errorView != nil)
[errorView release]; //Always crashes because errorView is never nil even though it has been assigned nil?
}
我正在为此拉头发。除了描述的这些方法之外,errorView 变量在其他任何地方都没有使用,我能读到的所有内容都表明它是正确的方法。
【问题讨论】:
-
这是实际代码还是最小示例?因为您在 init 和 dealloc 方法中缺少 if((self = [super init])) 和 [super dealloc] 调用...
-
问题可能不在于
errorView本身。会不会是您发布了两次UITableViewController(或超过您应该发布的次数)?这将导致为无效的UITableViewController对象调用dealloc方法,该对象可能在errorView变量上有垃圾。 -
这是一个非常精简的版本,是的,原版确实有提到的例程。 UITableViewController 会在视图控制器弹出时自动释放。 (在创建并推入父视图控制器之后)
-
听起来还是有东西正在写入
errorView变量所在的内存位置。你确定dealloc只被调用一次吗?如果这不是问题,也许您在errorView之前的一块内存中存在某种缓冲区溢出,这会覆盖该变量上的值?有时当变量莫名其妙地改变它们的值时,实际上是其他人写出了他们分配的内存位置。 -
尝试简化问题:当然,此时它可能崩溃的唯一方法是如果 errorView 已被释放但未分配为零? (或从未分配给任何东西)。这两种情况都不是真的。
标签: objective-c uitableview memory-management uiview