1

我有一个名为“主机”的 UIView,其中包含许多其他视图。Host 是 glView 的子视图。主机也是一个实例变量。所以我有以下方法:

-(void) doCancel:(id)sender {
    ANNOUNCE
    X.messageIsShowing = NO;
    CGFloat fadeOutTime = 0.4f;
    [UIView animateWithDuration:fadeOutTime animations:^{ 
        host.alpha = 0.f; 
    } completion:^(BOOL finished){
        [host removeFromSuperview];
        [host release];
    }];
}

它应该淡出主机视图,然后将其从其超级视图中删除。它工作了几个星期,但现在它在“[host removeFromSuperview];”行上出现 EXC_BAD_ACCESS 崩溃。自从它起作用以来,我确实改变了很多东西,但据我所知,这种方法没有任何改变。

我添加了日志语句,所以现在它看起来像这样:

-(void) doCancel:(id)sender {
    ANNOUNCE
    X.messageIsShowing = NO;
    CGFloat fadeOutTime = 0.4f;
    CCLOG(@"host.alpha: %f", host.alpha);
    [UIView animateWithDuration:fadeOutTime animations:^{ 
        host.alpha = 0.f; 
    } completion:^(BOOL finished){
        CCLOG(@"host.alpha: %f", host.alpha);
        CCLOG(@"host %@", host);
        CCLOG(@"[host superview]: %@", [host superview]);
        [host removeFromSuperview];
        [host release];
    }];
}

所有四个日志语句都工作并打印预期的内容。所以'host'和host的superview对于日志语句是有效的。但它仍然在 [host removeFromSuperview] 上崩溃。我还玩了很多断点。但是调试命令在完成块内不起作用 - 没有任何 ivars 在范围内,可能是因为完成块在线程 1 而不是 0 上运行。谁能告诉我这里发生了什么?

4

1 回答 1

1

看看[host release]块的内部。我猜这host是一个实例变量?(它似乎不是一个局部变量。)如果是这样,在你释放它之后,你应该将它设置为nil,比如

[host release];
host = nil;

否则,它可能指向一个已释放的对象,下一个使用它的地方会崩溃。

于 2012-07-21T08:44:52.223 回答