Ios 什么';这个街区怎么了?
我有一个名为“主机”的UIView,其中包含许多其他视图。Host是glView的子视图。主机也是一个实例变量。所以我有以下方法:Ios 什么';这个街区怎么了?,ios,animation,objective-c-blocks,Ios,Animation,Objective C Blocks,我有一个名为“主机”的UIView,其中包含许多其他视图。Host是glView的子视图。主机也是一个实例变量。所以我有以下方法: -(void) doCancel:(id)sender { ANNOUNCE X.messageIsShowing = NO; CGFloat fadeOutTime = 0.4f; [UIView animateWithDuration:fadeOutTime animations:^{ host.alpha =
-(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];
}];
}
它应该淡出主体视图,然后将其从superview中删除。它工作了几个星期,但现在它在线路“[host removeFromSuperview]”上的EXC_BAD_访问崩溃了。我确实改变了很多东西,因为它起作用了,但就我所知,这种方法没有任何改变
我添加了日志语句,因此现在看起来如下所示:
-(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];
}];
}
所有四个日志语句都工作并打印预期内容。因此,“主机”和主机的superview对日志语句有效。但它仍然在[host removeFromSuperview]上崩溃。我还玩了很多断点。但是调试命令在完成块内不起作用——所有IVAR都不在范围内,可能是因为完成块在线程1而不是0上运行。有人能告诉我这里发生了什么吗?看看区块内的
[host release]
。我猜host
是一个实例变量?(它似乎不是局部变量。)如果是这样,在释放它之后,应该将其设置为nil
,如
[host release];
host = nil;
否则,它可能指向解除分配的对象,下一个使用它的位置将崩溃。查看块内的
[host release]
。我猜host
是一个实例变量?(它似乎不是局部变量。)如果是这样,在释放它之后,应该将其设置为nil
,如
[host release];
host = nil;
否则,它可能指向解除分配的对象,下一个使用它的位置将崩溃。
-removeFromSuperView
已经在MRC环境中的视图中调用了release,不需要额外的版本,特别是因为视图现在由子视图树所有。如果保留了它,则需要[host release]。例如,使用alloc创建保留的property.host,然后将其添加到glView。因此,从glView(即superview)中删除它仍然需要一个版本来平衡alloc。事实上,我在[host removeFromSuperview]之前放了一个log语句来显示retainCount,它是2。我也放了一个log语句来显示循环中'finished'的值,它是1(即是)。-removeFromSuperview
已经在MRC环境中调用了视图中的release,不需要额外的release,特别是因为该视图现在由子视图树拥有。如果您保留了它,则需要[host release]。例如,使用alloc创建保留的property.host,然后将其添加到glView。因此,从glView(即superview)中删除它仍然需要一个版本来平衡alloc。事实上,我在[host removeFromSuperview]之前放了一个log语句来显示retainCount,它是2。我也放了一个log语句来显示循环中'finished'的值,它是1(即是)。我给这个答案一个检查,因为它让我解决了这个问题,尽管我认为将host设置为nil的部分无关紧要。但在完成块中的[主机释放]可能永远不会起作用。我把日志语句放在任何我能想到的地方,试图准确地跟踪到底发生了什么,但它仍然令人费解。我正在对此进行检查,因为它使我想到了一个解决问题的思路,但我认为将主机设置为零是不相关的。但正如newacct所说,在一个完成块中[主机释放]可能是个坏主意。有了更多的log语句,我发现retain计数并不像动画语句中预期的那样工作。例如,它在方法开始时“神秘地”增加,然后通过[host removeFromSuperview]减少2。我修改了主机的分配和初始化方式,然后我可以从完成块中删除[host release],崩溃就消失了。@RobertL:不,我不是说在块中有[host release]
是有问题的。(它是对象的一个实例变量。您可以在处理完它后释放它。)这只是释放,而不将其设置为nil
,这是有问题的。是的。但没有将其设置为零并不是导致此特定问题的原因。主机=零;这是一个很好的实践,但在这种情况下,我再也没有使用过主机,所以这并不重要。[host release]导致了问题,通过将其移动到其他地方,问题得到了修复。@RobertL:[host release]
导致问题的唯一方法是主机
指向已解除分配的对象。我不知道您在“如何分配和初始化主机”方面做了哪些不同的工作;但是,例如,如果您没有保留host
最初指向的对象,这将解释它(需要保留实例变量指向的对象,否则下次尝试使用时可能会取消分配它们);或者,如果您在其他地方未将主机设置为nil而执行了[host release]
,也可以解释这一点。我检查一下这个答案,因为它使我解决了这个问题,尽管我认为有关将主机设置为nil的部分无关紧要。但在完成块中的[主机释放]可能永远不会起作用。我把日志语句放在任何我能想到的地方,试图准确地跟踪到底发生了什么,但它仍然令人费解。我正在对此进行检查,因为它使我想到了一个解决问题的思路,但我认为将主机设置为零是不相关的。但正如newacct所说,在一个完成块中[主机释放]可能是个坏主意。有了更多的log语句,我发现retain计数并不像动画语句中预期的那样工作。例如,它在方法开始时“神秘地”增加,然后通过[host removeFromSuperview]减少2。我修改了主机的分配和初始化方式,然后我可以从完成块中删除[host release],崩溃就消失了。@RobertL:不,我不是说在块中有[host release]
是有问题的。(这是一个