xcode AVAudioPlayer 内存泄漏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1352588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AVAudioPlayer memory leak
提问by Adi
I'm stuck on some weird memory leak problem related to the AVAudioPlayer and I need help after trying everything that came to mind.
我遇到了一些与 AVAudioPlayer 相关的奇怪内存泄漏问题,在尝试了所有想到的东西后我需要帮助。
Here is the short description of the problem - code appears right after. I initialize my player and start to play the sound track in an endless loop (and endless loop or one time play did not change the problem). Several seconds after the music started, I switch to another sound track, hence I create a new player, initialize it, release the old one (which is playing) and then set the new one in place and play it.
这是问题的简短描述 - 代码紧随其后。我初始化我的播放器并开始无限循环播放音轨(无限循环或一次播放并没有改变问题)。音乐开始几秒钟后,我切换到另一个音轨,因此我创建了一个新播放器,初始化它,释放旧播放器(正在播放),然后将新播放器放置到位并播放。
At that point in time (right after I call the new Player - [Player play]) I get a memory leak (of 3.5Kb).
在那个时间点(就在我调用新 Player - [Player play] 之后)我得到了内存泄漏(3.5Kb)。
I tried the following:
我尝试了以下方法:
Stop the old player and then release it - no effect
Release the Player right after the play instruction - did not start playing
Release twice the old player - crash
Memory leak DOES NOT happen when I create and play the first Player!
停止旧播放器然后释放它 - 没有效果
在播放指令后立即释放播放器 - 没有开始播放
两次释放老玩家——崩溃
当我创建和播放第一个 Player 时不会发生内存泄漏!
Also, in the reference it does say that the 'play' is async and so probably it increases the ref count by 1, but in this case, why didn't [Player stop] help?
此外,在参考文献中它确实说“播放”是异步的,因此可能会将引用计数增加 1,但在这种情况下,为什么 [Player stop] 没有帮助?
Thanks,
谢谢,
Here are some parts of the code about how I use it:
以下是有关我如何使用它的代码的一些部分:
- (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;
}
}
回答by bentford
Here is method to create AVAudioPlayer without causing memory leaks. See this page for explaination.
这是创建 AVAudioPlayer 而不会导致内存泄漏的方法。 有关说明,请参阅此页面。
I have confirmed in my app that this removed my AVAudioPlayer leaks 100%.
我已经在我的应用程序中确认这消除了我的 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;
}
回答by bendu
Implement the protocol AVAudioPlayerDelegate and its method audioPlayerDidFinishPlaying:successfully: then release the audio player object
实现协议 AVAudioPlayerDelegate 及其方法 audioPlayerDidFinishPlaying:successfully: 然后释放音频播放器对象
eg.
例如。
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player release]; // releases the player object
}
回答by peterb
Your code looks OK to me as far as I've seen, so maybe there is code elsewhere which is causing the problem.
就我所见,您的代码对我来说看起来不错,所以也许其他地方的代码导致了问题。
I will say that you're using a sort of odd idiom. Rather than retaining on create and releasing on set, I'd do something like this:
我会说你在使用一种奇怪的习语。与其在片场继续创作和发布,我会做这样的事情:
// 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];
}
In this way, you only retain "player" objects when they actually come into your setAudioPlayer method, which might make it easier to track down.
通过这种方式,您只会在“播放器”对象真正进入您的 setAudioPlayer 方法时才保留它们,这可能会更容易追踪。
Also, verify that it's actually an AVAudioPlayer object which is leaking. Instruments should be able to verify this for you.
另外,验证它实际上是一个正在泄漏的 AVAudioPlayer 对象。仪器应该能够为您验证这一点。
回答by ahmet emrah
Try adding MediaPlayer.framework to your project
尝试将 MediaPlayer.framework 添加到您的项目中