按下按钮时会发生setImage上的EXC_BAD_ACCESS,但不会发生异步调用setImage

时间:2011-07-29 22:59:19

标签: memory-management ios4 uiimage

我有一个按钮,当我选择时,我想用它来显示艺术作品图像,但是如果没有选中,我想要显示背景图像。该按钮称为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];
        }

    }

}

所以,如果我运行上面的代码,就没有崩溃。但是,当我按下按钮时,艺术品的第一次显示是模糊的(因为从上面的逻辑可以看出,它使用的是10,10的cgsize)。但是现在已经选择了albumArtworkView按钮并且albumArtworkShowing标志现在为TRUE,每次后续执行handleChangesToArtwork都会将图稿的大小调整为albumArtworkView按钮的边界,并且图像不再模糊。

如果我修改了上面的handleChangesToArtwork例程,当albumArtworkShowing标志为FALSE时包含else,如下所示:

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

然后就是我得到一个EXC_BAD_ACCESS。选择按钮时,showAlbumArtwork方法中会出现此错误。具体来说,它出现在setImage的行上。

我怀疑我必须有一些内存管理问题,但我不知道在哪里。

任何人都可以看到我的方式错误吗?

1 个答案:

答案 0 :(得分:1)

更改

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

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

这将确保使用artworkImage属性的setter,它保留实例。在当前代码中,您将自动释放的UIImage分配给artworkImage而不保留它,从而导致EXC_BAD_ACCESS。