2010-11-08 55 views
1

我想了解一些關於AVAudioPlayer和AVAudioRecorder的內存問題。AVAudioPlayer內存管理

我創建AVAudioRecorder:

-(void)loadAudioForPage { 
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:recordSettings error:&err]; 

self.audioRecorder = recorder; 
[recorder release]; 

}

此方法將它駐留在所述控制器的壽命期間被調用多次,並且每一次的屬性audioFileURL將是不同的。

我已經將錄像機分配給我的視圖控制器的實例變量,屬性保留它,所以我釋放。

現在,如果我只是在dealloc中發佈audioRecorder,所有可能都會很好,除非我需要在調用dealloc之前將另一個實例指定給該屬性。

所以,我的想法是把它的委託方法:

-(void) audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag { 

[audioRecorder release]; 
self.audioRecorder = nil; 

} 

然而,這崩潰。有人可以向我解釋爲什麼? AVAudioRecorder是否會自動釋放,即使我已經分配了它?我是如何保留它兩次的,第二次釋放它會崩潰(EXEC_BAD_ACCESS)?

回答

1

當您使用生成的屬性訪問器時,它們爲您管理所有內存。因此,如果將該屬性設置爲零,並且以前有另一個值,則會釋放舊值,然後將當前值設置爲零。

因此,在您的代碼中,這會導致釋放該屬性的前一個對象兩次(直接由您和屬性訪問器直接設置爲零時)。您必須直接管理財產或讓訪問者管理財產。

所以,要麼:

[audioRecorder release]; 
audioRecorder = nil; 

或:

[self setAudioRecorder:nil]; 

由於您使用的特性和生成的訪問,你應該只是堅持與和重寫你的委託方法:

-(void) audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag 
{ 
    [self setAudioRecorder:nil]; 
} 

你可能真的直接發佈財產的唯一地方是在dealloc方法。

+0

感謝您的洞察力。我不完全清楚。 – isaac 2010-11-09 00:53:08

0

你的屬性audioRecorder可能是一個保留類型,所以在didFinish方法中,你不需要釋放它,因爲設置屬性爲零將爲你做。

AVAudioRecorder *recorder = [[[AVAudioRecorder alloc] initWithURL:audioFileURL settings:recordSettings error:&err] autorelease]; 

self.audioRecorder = recorder; 

爲了清晰起見,可能會更好地爲您服務。雖然顯然autorelease在iOS中是不好的形式。不能想到爲什麼。