由于访问不当,在animateWithDuration之后崩溃

时间:2011-04-29 15:39:19

标签: iphone animation crash block

请参阅以下代码。它用图像显示动画效果。

UIImageView *imgView = [[UIImageView alloc] initWithImage:img];  // ref count = 1
int offX = imgView.frame.size.width / 6;
int offY = (imgView.frame.size.height - 44) / 6;
imgView.frame = CGRectMake(offX, offY, imgView.frame.size.width - offX * 2, 
                           (imgView.frame.size.height - 44) - offY * 2);
[overlayView addSubview:imgView];  // ref count = 2
[imgView release];  // ref count = 1
[UIView animateWithDuration:1.0 animations:^{
    [imgView setCenter:CGPointMake(TRASH_X, TRASH_Y)];
    [imgView setTransform:CGAffineTransformMakeScale(0.1, 0.1)];
    [imgView setAlpha:0.5];
} completion:^(BOOL finished) {
    [imgView removeFromSuperview]; // ref count = 0? destroy imgView object?
}];

从上面的代码中,如果我删除[imgView release],则没有崩溃。但是,上面的代码会使完成例程崩溃。为什么?我认为引用计数的变化与评论一样。然后应该没有崩溃。

你能解释为什么完成例程会崩溃吗?

3 个答案:

答案 0 :(得分:2)

行。我解决了我的问题。 事实上,问题不在我展示的代码中。这段代码没有问题。

崩溃的原因与'img'对象有关,它被用作UIImageView的初始参数。实际上,我不小心从另一个地方再次释放了它。

我认为当UIImageView对象解除分配时,尝试释放它的Image对象。但是,它已经解除分配,崩溃发生了。它看起来像[imgView removeFromSuperview]使崩溃。

很抱歉大惊小怪。

答案 1 :(得分:1)

这是我的两分钱:一旦释放imgView(// ref count = 1),该变量不再包含对象的引用。如果您计划进一步使用它,就像我看到您正在使用动画,您应该在之后发布它。希望这会有所帮助。

答案 2 :(得分:0)

虽然图像视图仍然被您添加到的视图引用,但没有任何对它的引用。在动画块之前调用[imgView release]后,您丢失了对图像视图的所有引用。根据经验,每个alloccopyretain都需要匹配releaseautorelease。虽然overlayView在内部保留了对该视图的引用,但您在任何地方都没有retain,所以只要您发布它,它就会消失。

我建议改为自动释放UIImageView。 (或者,您可以将release放在完成处理程序中。)

示例代码:

UIImageView *imgView = [[[UIImageView alloc] initWithImage:img] autorelease];  
int offX = imgView.frame.size.width / 6;
int offY = (imgView.frame.size.height - 44) / 6;
imgView.frame = CGRectMake(offX, offY, imgView.frame.size.width - offX * 2, 
                           (imgView.frame.size.height - 44) - offY * 2);
[overlayView addSubview:imgView]; 
[UIView animateWithDuration:1.0 animations:^{
    [imgView setCenter:CGPointMake(TRASH_X, TRASH_Y)];
    [imgView setTransform:CGAffineTransformMakeScale(0.1, 0.1)];
    [imgView setAlpha:0.5];
} completion:^(BOOL finished) {
    [imgView removeFromSuperview]; 
}];

修改

您可以尝试将[imageView removeFromSuperview];更改为:

if(imageView){
  [imageView removeFromSuperview];
}