dealloc中dispatch_async安全吗?

时间:2014-04-05 19:59:06

标签: objective-c

我有一个随机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

2 个答案:

答案 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];
    });
}

我还没有测试过这个