我有一个问题,我现在无法在2天内解决,它只发生在发布版本中,我在调试版本中运行时没有任何问题。
但我认为这是因为一块没有被执行。我有这样的崩溃报告:
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)
audioPlayerDidFinishPlaying的方法:成功如下:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
if (musicPlayerCompletionBlock)
dispatch_async(dispatch_get_main_queue(), musicPlayerCompletionBlock);
}
Block设置如下:
- (void)setMusicCompletionBlock:(void (^)(void))theBlock
{
musicPlayerCompletionBlock = theBlock;
}
在头文件中这样:
void (^musicPlayerCompletionBlock) (void);
答案 0 :(得分:8)
您需要在设置器中复制块。块从堆栈开始,在复制之前不会移动到堆。
它在调试版本中“起作用”,因为未启用优化器,因此编译器不会积极地重用堆栈。即它巧合。如果要在块创建和调用之间添加一个或两个方法调用,它可能会开始崩溃。
我建议你摆脱musicPlayerCompletionBlock
的setter / getter的自定义实现,只声明一个属性:
typedef void(^MusicCompletionBlockType)(void);
....
@property(copy) MusicCompletionBlockType musicCompletionBlock;
生成的setter / getter将负责复制块。如果不使用ARC,您可以在dealloc
中将其释放。