Is it safe to send dispas_async to dealloc?

I have random EXC_BAD_ACCESS KERN_INVALID_ADDRESS , but I can not specify the source. However, I am wondering if this could be:

I have an audio_queue created like this:

 _audio_queue = dispatch_queue_create("AudioQueue", nil); 

which I use to create and access an object named _audioPlayer :

  dispatch_async(_audio_queue, ^{ _audioPlayer = [[AudioPlayer alloc] init]; }); 

The audio player belongs to MovieView :

 @implementation MovieView { AudioPlayer *_audioPlayer } 

Then, in the dealloc MovieView method, I:

 - (void)dealloc { dispatch_async(_audio_queue, ^{ [_audioPlayer destroy]; }); } 

It is acceptable? I think that by the time the block is called, MovieView would have been freed, and when you try to access _audioPlayer it no longer exists. Is this the case?

My crash report says:

 MovieView.m line 0 __destroy_helper_block_ 
+7
objective-c
source share
2 answers

Your access error ivar. This is due to the way ivars work in ObjC: above -dealloc equivalent

 - (void)dealloc { dispatch_async(self->_audio_queue, ^{ [self->_audioPlayer stopPlaying]; }); } 

This may break because you end using self after it is released.

The fix is ​​something like

 - (void)dealloc { AVAudioPlayer * audioPlayer = _audioPlayer; dispatch_async(audio_queue, ^{ [audioPlayer stopPlaying]; }); } 

(This is often unsafe for streaming explicitly or implicitly (via ivars) the self link in the block. Unfortunately, I don't think there is a warning for this.)

+11
source share

If this is the reason, you can use dispatch_sync

 - (void)dealloc { dispatch_sync(_audio_queue, ^{ [_audioPlayer stopPlaying]; }); } 

I have not tested this

-2
source share

All Articles