我有一个随机EXC_BAD_ACCESS KERN_INVALID_ADDRESS
,但我不能指出来源。但是,我想知道这可能是它:
我有一个像这样创建的audio_queue:
_audio_queue = dispatch_queue_create("AudioQueue", nil);
用于创建和访问名为_audioPlayer
的对象:
dispatch_async(_audio_queue, ^{
_audioPlayer = [[AudioPlayer alloc] init];
});
音频播放器归MovieView
所有:
@implementation MovieView
{
AudioPlayer *_audioPlayer
}
然后,在dealloc
的{{1}}方法中,我有:
MovieView
这可以接受吗?我想在调用块时,- (void)dealloc
{
dispatch_async(_audio_queue, ^{
[_audioPlayer destroy];
});
}
已经被释放,并且在尝试访问MovieView
时,它不再存在。是这种情况吗?
我的崩溃报告只说:
_audioPlayer
答案 0 :(得分:11)
您的错误是在ivar访问中。这是因为ivars在ObjC中的工作原理:上面的-dealloc
等同于
- (void)dealloc
{
dispatch_async(self->_audio_queue, ^{
[self->_audioPlayer stopPlaying];
});
}
这可能会中断,因为您在解除分配后最终会使用self
。
修复就像是
- (void)dealloc
{
AVAudioPlayer * audioPlayer = _audioPlayer;
dispatch_async(audio_queue, ^{
[audioPlayer stopPlaying];
});
}
(在一个区块中明确地或隐含地(通过ivars)引用self
通常不是线程安全的。遗憾的是,我不认为有这样的警告。)
答案 1 :(得分:-2)
如果这是原因,您可以使用dispatch_sync
- (void)dealloc
{
dispatch_sync(_audio_queue, ^{
[_audioPlayer stopPlaying];
});
}
我还没有测试过这个