EXC_BAD_ACCESS на setImage происходит при нажатии кнопки, но не с асинхронным вызовом setImage - PullRequest
0 голосов
/ 30 июля 2011

У меня есть кнопка, которую, когда она выбрана, я хочу использовать для отображения изображения произведения искусства, но когда она не выбрана, я хочу отобразить фоновое изображение. Кнопка называется кнопкой albumArtworkView и по сути является переключателем между режимами отображения. Находясь в выбранном состоянии, новые изображения периодически отображаются. Чтобы отображаемое изображение было четким, я обнаружил, что размер иллюстрации должен быть изменен до границ кнопки albumArtworkView, как показано в строках следующей процедуры:

-(void) handleChangesToArtwork {
    ...
    MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork];
    if (artwork) {
        artworkImage = [artwork imageWithSize: CGSizeMake (10, 10)]; // size for nav button
    }

    ...

    if (albumArtworkShowing) {
        artworkImage = [artwork imageWithSize: albumArtworkView.bounds.size]; // resize artwork for albumArtworkView button
        [albumArtworkView setImage:artworkImage forState: UIControlStateNormal];
    }
    ...
}

Теперь artworkImage и albumArtworkView определены следующим образом:

@interface RootViewController : UIViewController <...> {
UIImage           *artworkImage;
IBOutlet UIButton *albumArtworkView;
}

-(IBAction) showAlbumArtwork:(id)sender;

@property (nonatomic, retain) UIImage           *artworkImage;
@property (nonatomic, retain) IBOutlet UIButton *albumArtworkView;

Обратите внимание на определение метода showAlbumArtwork для обработки действия выбора кнопки. Этот метод реализован следующим образом:

-(IBAction) showAlbumArtwork:(id)sender {
    if (albumArtworkShowing) {
        [self setAlbumArtworkShowing:FALSE];
        [albumArtworkView setImage:[UIImage imageNamed: @"backgroundImage.png"] forState: UIControlStateNormal];
    }
    else {
        [self setAlbumArtworkShowing:TRUE];
        if (artworkImage) {
            [albumArtworkView setImage:artworkImage forState: UIControlStateNormal];    // Now change the look of the albumArtworkView (speaker button) to the newly sized artworkImage
        }
        else {
            [albumArtworkView setImage:[UIImage imageNamed: @"no_artwork.png"] forState: UIControlStateNormal];
        }

    }

}

Итак, если я запускаю приведенный выше код, сбоев нет. Тем не менее, первое отображение рисунка, когда я нажимаю кнопку, является нечетким (потому что, как вы можете видеть из приведенной выше логики, он использует cgsize 10,10). Но теперь, когда кнопка albumArtworkView была выбрана и флаг albumArtworkShowing теперь имеет значение ИСТИНА, каждое последующее выполнение handleChangesToArtwork изменяет размеры графического объекта до границ кнопки albumArtworkView, и изображения перестают быть нечеткими.

Если я изменю подпрограмму handleChangesToArtwork, указанную выше, чтобы включить else, когда флаг albumArtworkShowing имеет значение FALSE, как показано ниже:

-(void) handleChangesToArtwork {
    ...
    if (albumArtworkShowing) {
        ...
    }
    else {
        artworkImage = [artwork imageWithSize: albumArtworkView.bounds.size];
    }
}

тогда я получаю EXC_BAD_ACCESS. Эта ошибка возникает в методе showAlbumArtwork при нажатии кнопки. В частности, это происходит в строке с setImage.

Я подозреваю, что у меня должна быть проблема с управлением памятью, но я не уверен, где.

Кто-нибудь может увидеть ошибки моих путей?

1 Ответ

1 голос
/ 30 июля 2011

Изменение

artworkImage = [artwork imageWithSize: albumArtworkView.bounds.size];

до

self.artworkImage = [artwork imageWithSize: albumArtworkView.bounds.size];

Это обеспечит использование установщика свойства artworkImage, который сохраняет экземпляр. В вашем текущем коде вы присваиваете автоматически выпущенный UIImage для artworkImage, не сохраняя его, вызывая EXC_BAD_ACCESS.

...