使用 AVAudioPlayer 的内存泄漏

Posted

技术标签:

【中文标题】使用 AVAudioPlayer 的内存泄漏【英文标题】:Memory leak using AVAudioPlayer 【发布时间】:2011-03-12 18:10:25 【问题描述】:

我正在使用仪器分析我的 Objective-C++ 代码中的泄漏,我得到了这个:

Leaked Object   Address Size    Responsible Library Responsible Frame
Malloc 32 Bytes,0x8135bc0   32 Bytes    AudioToolbox    SimAggregateDevice::SimAggregateDevice(__CFString const*, __CFString const*, long&)
__NSCFDictionary,0x8135be0  48 Bytes    AudioToolbox    CreateDictionaryForDevice(unsigned long)
Malloc 32 Bytes,0x8135c10   32 Bytes    AudioToolbox    CreateDictionaryForDevice(unsigned long)
Malloc 32 Bytes,0x8135c30   32 Bytes    AudioToolbox    CreateDictionaryForDevice(unsigned long)
Malloc 48 Bytes,0x8135c50   48 Bytes    AudioToolbox    SimAggregateDevice::SimAggregateDevice(__CFString const*, __CFString const*, long&)
__NSCFDictionary,0x813a820  48 Bytes    AudioToolbox    SimAggregateDevice::SimAggregateDevice(__CFString const*, __CFString const*, long&)
__NSCFArray,0x813a850   32 Bytes    AudioToolbox    SimAggregateDevice::SimAggregateDevice(__CFString const*, __CFString const*, long&)
__NSCFDictionary,0x813a870  48 Bytes    AudioToolbox    CreateDictionaryForDevice(unsigned long)
Malloc 32 Bytes,0x813a8a0   32 Bytes    AudioToolbox    SimAggregateDevice::SimAggregateDevice(__CFString const*, __CFString const*, long&)
Malloc 32 Bytes,0x813a8d0   32 Bytes    AudioToolbox    CreateDictionaryForDevice(unsigned long)

我认为这与我编写的用于在应用程序启动时播放声音的代码有关。我是这样做的:这个方法是在 applicationDidFinishLaunching::

中调用的
- (void)playJingle 
    // This is a detached thread so I need a new pool.
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    // This audio player will be released in  audioPlayerDidFinishPlaying.
    NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:@"jingle" ofType:@"m4a"];
    AVAudioPlayer *av = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:NULL];
    [av setDelegate:self];
    [av play];

    // Release.
    [pool release];


- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)av successfully:(BOOL)flag

    // Release the AVAudioPlayer.
    [av release];

在后台线程中(通过 performSelectorInBackground:withObject: 调用)。我错过了什么吗?为什么我有这些泄漏? 谢谢!

【问题讨论】:

【参考方案1】:

您是否尝试过在设备上运行该应用程序? AVAudioPlayer 在模拟器上通过内存泄漏检测容易出现误报...

Here's a very similar question with a similar looking leak report

【讨论】:

很遗憾我很少能在真机上测试,所以我只是想知道我使用和释放对象的方式是否有任何错误。确实,我在其他人周围看到过类似的报告,但并不完全相同。那么,我是否应该期望模拟器中的泄漏可能会在真实设备上消失?或者这是一个例外?谢谢! 您很少会看到在模拟器中显示的泄漏,而不是在物理设备中显示的泄漏,但是对于某些库,它可能会发生。你对 AVAudioPlayer 的使用对我来说很好!【参考方案2】:

这不行,你将AVPlayer分配给一个局部变量:

AVAudioPlayer *av = ...

而不是实例变量。

-(void>) playJinlge
    ...
    self.av = .....


-(void) didfinish ... 
   [self.av release];
   self.av=nil;

【讨论】:

我为什么需要这样做?指向 AVAudioPlayer 的指针由 audioPlayerDidFinishPlaying 提供。

以上是关于使用 AVAudioPlayer 的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

AVAudioPlayer 导致内存泄漏

在 NSTimer 中播放 AVAudioPlayer,没有内存泄漏?

iOS6 中的 AudioToolBox 泄漏?

如何播放与 AVAudioPlayer 重叠的相同声音?

iOS:将 AVAudioPlayer 的实例从一个变量移动到另一个变量

使用 AVAudioPlayer 处理钢琴样本——内存管理