I have a problem I haven’t been able to solve in 2 days now, and it only happens in the release build, I dont have any problem when I run it in the debug build.
But I think it is because of a block that isn’t getting executed. I have a crash report like this:
3 libdispatch.dylib 0x375d1c34 _dispatch_Block_copy + 8
4 libdispatch.dylib 0x375dc4ca dispatch_async$VARIANT$up + 6
5 Koldkrigsspionen 0x00020ef2 -[NOAudioManager audioPlayerDidFinishPlaying:successfully:] (NOAudioManager.m:807)
The method of audioPlayerDidFinishPlaying:successfully is like this:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
if (musicPlayerCompletionBlock)
dispatch_async(dispatch_get_main_queue(), musicPlayerCompletionBlock);
}
Block is set like this:
- (void)setMusicCompletionBlock:(void (^)(void))theBlock
{
musicPlayerCompletionBlock = theBlock;
}
Like this in the header file:
void (^musicPlayerCompletionBlock) (void);
You need to copy the block in your setter. Blocks start out on the stack and don’t move to the heap until copied.
It “works” in debug builds because the optimizer isn’t enabled and, thus, the compiler doesn’t aggressively reuse the stack. I.e. it works by coincidence. If you were to add a method call or two between the blocks creation and invocation, it would likely start crashing.
I would recommend that you get rid of the custom implementations of the setter/getter for
musicPlayerCompletionBlockand just declare a property:The generated setter/getter will take care of copying the block. You can release it in
dealloc, if not using ARC.