Сбой после animateWithDuration из-за плохого доступа - PullRequest
1 голос
/ 29 апреля 2011

Пожалуйста, смотрите код ниже. Показывает эффект анимации с изображением.

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 ]

2 голосов
/ 29 апреля 2011

OK.Я решил свою проблему.На самом деле, проблема не была в коде, который я показал.В этом коде проблем не было.

Причина сбоя связана с объектом 'img', который используется в качестве начального аргумента UIImageView.На самом деле, я случайно выпустил его еще раз из другого места.

Я думаю, что когда объект UIImageView освобожден, он пытается освободить его объект Image.Но, это уже освобождено так, крах произошел.Похоже, что [imgView removeFromSuperview] вызывает сбой.

Извините за суету.

1 голос
/ 29 апреля 2011

Вот мои два цента: как только вы отпустите imgView (// ref count = 1), эта переменная больше не будет содержать ссылку на ваш объект.Если вы планируете использовать его дальше, как я вижу, вы делаете с анимацией, вы должны выпустить его позже.Надеюсь, это поможет.

0 голосов
/ 29 апреля 2011

Хотя на представление изображения все еще ссылается представление, к которому вы добавили его, вы не имеют на него никаких ссылок. После того, как вы позвоните [imgView release] перед блоком анимации, вы потеряете все ссылки на изображение. Практическое правило заключается в том, что для каждого alloc, copy и retain требуется соответствие release или autorelease. Хотя 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]; 
}];

EDIT:

Вы можете попробовать изменить [imageView removeFromSuperview]; на:

if(imageView){
  [imageView removeFromSuperview];
}
...