2012-08-04 89 views
3

我有一個問題,我現在還沒有能夠解決的問題,它只發生在發佈版本中,我沒有任何問題,當我在調試版本中運行它時。發佈版本上的塊崩潰

但我認爲這是因爲一個塊沒有被執行。我有一個這樣的崩潰報告:

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); 
} 

塊設置這樣的:

- (void)setMusicCompletionBlock:(void (^)(void))theBlock 
{ 
    musicPlayerCompletionBlock = theBlock; 
} 

這樣在頭文件:

void (^musicPlayerCompletionBlock) (void); 
+0

你在哪裏定義塊,以及如何存儲它?另外,你使用的是ARC嗎? – 2012-08-04 11:08:50

+0

該塊在另一個對象中定義,如下所示: [[NOAudioManager sharedManager] setMusicCompletionBlock:^ {self videoDidFinish]; }]; 是的,我正在使用ARC。 音頻播放完畢。該應用程序在發佈版本中崩潰。 – WYS 2012-08-04 12:08:58

+0

請編輯原始問題以包含正確格式化的信息。這將有助於澄清未來讀者的問題,並且在評論中非常難以閱讀。 – 2012-08-04 12:38:46

回答

8

你需要在你的setter中複製這個塊。塊開始在堆棧上,並且不會移動到堆上直到被複制。

它在調試版本中「起作用」,因爲優化器未啓用,因此編譯器不積極地重用堆棧。即它巧合地工作。如果要在塊創建和調用之間添加一個或兩個方法調用,它可能會開始崩潰。

我建議你擺脫的setter /吸氣劑爲musicPlayerCompletionBlock定製實現的,只是聲明一個屬性:

typedef void(^MusicCompletionBlockType)(void); 
.... 
@property(copy) MusicCompletionBlockType musicCompletionBlock; 

生成的setter /吸氣將採取複製塊的照顧。如果不使用ARC,您可以在dealloc中釋放它。

+0

Omfg解決了我的問題!非常感謝,你救了我的一天!也許有人可以解釋爲什麼這在調試模式下工作,而不是釋放? – WYS 2012-08-04 13:45:47

相關問題