Please see the below 开发者_开发知识库code. It shows animation effect with image.
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?
}];
From the above code, if I remove [imgView release] there is no crash. but, the above code makes crash from the completion routine. Why? As I think reference count changed as like the comment. Then there should be no crash.
Could you please explain why the completion routine makes crash?
OK. I solved my problem. In fact, problem was not in the code I showed. There was no problem in this code.
The reason of crash is related with 'img' object which is used as initial argument of UIImageView. Actually, I accidentally released it one more time from the other place.
I think when UIImageView object deallocated it try to release it's Image object. But, it's already deallocate so, crash happend. It just looks like [imgView removeFromSuperview] makes crash.
Sorry for fuss.
Here is my two cents: Once you release imgView (//ref count = 1) that variable no longer contains a reference to your object. If you plan on using it further ahead, like I see you are doing with the animation, you should release it afterwards. Hope this helps.
Although the image view is still referenced by the view which you've added it to, you don't have any references to it. Once you call [imgView release]
, before the animate block, you've lost all of your references to the image view. The rule of thumb is that every alloc
, copy
, and retain
requires a matching release
or autorelease
. Although the overlayView
internally retains a reference to the view, you did not retain
it anywhere, so as soon as you release it, it's gone.
I suggest autoreleasing the UIImageView instead. (Or, you may be able to put the release
in the completion handler.)
Sample Code:
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];
}];
EDIT:
You can try changing [imageView removeFromSuperview];
to:
if(imageView){
[imageView removeFromSuperview];
}
精彩评论