7

我遇到了一些与 AVAudioPlayer 相关的奇怪内存泄漏问题,在尝试了所有想到的事情后我需要帮助。

这是问题的简短描述 - 代码紧随其后。我初始化我的播放器并开始无限循环播放音轨(无限循环或一次播放并没有改变问题)。音乐开始几秒钟后,我切换到另一个音轨,因此我创建了一个新播放器,对其进行初始化,释放旧播放器(正在播放),然后将新播放器放置到位并播放。

在那个时间点(就在我调用新播放器 - [播放器播放]之后)我得到了内存泄漏(3.5Kb)。

我尝试了以下方法:

  • 停止旧播放器然后释放它 - 没有效果

  • 播放指令后立即释放播放器 - 未开始播放

  • 释放两次旧播放器 - 崩溃

  • 当我创建和播放第一个播放器时,不会发生内存泄漏!

此外,在参考文献中确实说“播放”是异步的,因此可能会将 ref 计数增加 1,但在这种情况下,为什么 [Player stop] 没有帮助?

谢谢,

以下是有关我如何使用它的代码的一些部分:

- (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;

}

4

4 回答 4

7

这是创建 AVAudioPlayer 而不会导致内存泄漏的方法。 有关说明,请参阅此页面

我已经在我的应用程序中确认这消除了我的 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;
}
于 2009-11-19T19:44:58.227 回答
2

实现协议 AVAudioPlayerDelegate 及其方法 audioPlayerDidFinishPlaying:successfully: 然后释放音频播放器对象

例如。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [player release]; // releases the player object
}
于 2011-06-30T21:33:32.317 回答
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 对象。仪器应该能够为您验证这一点。

于 2009-08-30T13:11:52.373 回答
-2

尝试将 MediaPlayer.framework 添加到您的项目中

于 2009-11-25T11:46:05.183 回答