2009-08-29 43 views
6

我被困在與AVAudioPlayer相關的一些奇怪的內存泄漏問題上,在嘗試了所有想到的東西之後,我需要幫助。AVAudioPlayer內存泄漏

下面是問題的簡短描述 - 代碼出現後。 我初始化了我的播放器並開始在無限循環中播放音軌(無限循環或一次播放並未改變問題)。 音樂開始幾秒鐘後,我切換到另一首音軌,因此我創建了一個新的播放器,初始化它,釋放舊的(正在播放的),然後設置新的播放器並播放它。在那個時間點(在我稱爲新玩家 - [玩家玩]之後),我得到一個內存泄漏(3.5Kb)。

我試過如下:

  • 停止老玩家,然後釋放它 - 沒有影響

  • 版本播放器的播放指令後,正確的 - 沒有開始踢

  • 釋放兩次舊玩家 - 崩潰

  • 內存泄漏當我創建並播放內容時不會發生第一個玩家!

此外,在參考它說,「玩」是異步,因此它很可能通過增加1引用計數,但是在這種情況下,爲什麼沒有[播放器停止]幫助?

感謝,

下面是我如何使用它的代碼的某些部分:

- (void) loadAndActivateAudioFunction { 
NSBundle  *mainBundle = [NSBundle mainBundle]; 
NSError   *error; 
NSURL   *audioURL = [NSURL fileURLWithPath:[mainBundle pathForResource: Name ofType: Type]]; 
AVAudioPlayer *player = [(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error]; 

if (!player) { 
    DebugLog(@"Audio Load Error: no Player: %@", [error localizedDescription]); 
    DuringAudioPrep = false; 
    return; 
} 
[self lock]; 
[self setAudioPlayer: player]; 
[self ActivateAudioFunction]; 
[self unlock]; 

}

- (void) setAudioPlayer : (AVAudioPlayer *) player { 
if (Player) 
{ 
    if ([Player isPlaying] || Repeat) // The indication was off??? 
     [Player stop]; 
    [Player release]; 
} 
Player = player; 

}

- (void) ActivateAudioFunction { 
[Player setVolume: Volume]; 
[Player setNumberOfLoops: Repeat];  
[Player play]; 

DuringAudioPrep = false; 

}

回答

0

就我所見,您的代碼對我來說看起來還不錯,所以也許在其他地方存在導致問題的代碼。

我會說你正在使用一種奇怪的成語。而不是保留在創建和釋放的一套,我會做這樣的事情:

// new players will always be created autoreleased. 
    AVAudioPlayer *player = [[(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error] autorelease]; 

- (void) setAudioPlayer : (AVAudioPlayer *) player 
{ 
    if (Player) 
    { 
     if ([Player isPlaying] || Repeat) // The indication was off??? 
      [Player stop]; 
     [Player release]; 
    } 
    Player = [player retain]; 
} 

這樣,你只保留「玩家」的對象時,他們實際上進入你的setAudioPlayer方法,它可能更容易追查。

另外,請驗證它實際上是一個正在泄漏的AVAudioPlayer對象。儀器應該能夠爲您驗證。

+0

感謝您的回答。 是的 - 我確認它是帶有樂器的AVAudioPlayer。 至於方法 - 我使用這一個,因爲我實際上保存了不同的曲目,並通過匹配名稱並且如果它們沒有播放(而不是幾次下載相同的曲目)來重複使用它們。 因爲我知道我做了一個'Alloc'後,從調用者得到玩家,我知道它已被保留(除非我錯了?) – Adi 2009-08-31 07:21:31

7

這裏是創建AVAudioPlayer而不導致內存泄漏的方法。 See this page for explaination

我已經在我的應用程序中證實,這刪除了我的AVAudioPlayer泄漏100%。

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path { 
    NSData *audioData = [NSData dataWithContentsOfFile:path]; 
    AVAudioPlayer *player = [AVAudioPlayer alloc]; 
    if([player initWithData:audioData error:NULL]) { 
     [player autorelease]; 
    } else { 
     [player release]; 
     player = nil; 
    } 
    return player; 
} 
+1

我認爲應該鍵入NSData * audioData在第二個行... – SpaceDog 2010-08-07 19:30:02

+0

這段代碼真的很奇怪,沒有理由將alloc和init調用分開。爲更好的一般方法,請參閱http://stackoverflow.com/questions/17603551/arc-forbids-autorelease/17604365#17604365或者你可以添加autorelease像[[[AVAudioPlayer分配] initWithData:audioData錯誤:NULL] autorelease ] – MoDJ 2013-07-15 22:08:52

-2

嘗試增加MediaPlayer.framework到項目

+0

'MediaPlayer.framework'? 'AVAudioPlayer'位於'AVFoundation.framework'中,不需要'MediaPlayer'。謹慎闡述? – 2011-05-23 13:23:34

2

實現協議AVAudioPlayerDelegate及其方法audioPlayerDidFinishPlaying:成功:再鬆開音頻播放器對象

如。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { 
    [player release]; // releases the player object 
}