iOS6 中的 AudioToolBox 泄漏?
Posted
技术标签:
【中文标题】iOS6 中的 AudioToolBox 泄漏?【英文标题】:AudioToolBox leak in iOS6? 【发布时间】:2012-09-23 14:11:44 【问题描述】:当我使用 AudioToolBox 播放音乐时,内存泄漏严重。
AVAudioPlayer *newMusicPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];
我使用此代码播放音乐。在 ios5 和 iOS4 中,它可以正常工作。但是在iOS6中,如果数据大小为5M,则5M全部泄露。而且我在 Instruments 中看不到泄漏信息。
有人遇到同样的问题吗?任何建议将不胜感激。
我所有的音频代码都在这里(使用 ARC):
@implementation ViewController
AVAudioPlayer *_player;
- (void)play
if (_player)
[_player stop];
_player = nil;
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"test.app/1.mp3"];
NSData *musicData = [[NSData alloc] initWithContentsOfFile:path];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:musicData error:nil];
player.volume = 1;
if (player)
_player = player;
- (void)viewDidLoad
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(100, 100, 100, 100);
[button setTitle:@"play" forState:UIControlStateNormal];
[button addTarget:self action:@selector(play) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
@end
【问题讨论】:
检查发行说明确实有一些变化!在 ios6 您是否观察到iOS模拟器或设备中的内存泄漏?还是两者兼而有之? 在模拟器中。事实上,我无法在 4.5 的 Instruments 中获取设备上的 objc 符号,只有 c 符号显示 @matheszabi 我在developer.apple.com/library/ios/#releasenotes/General/… 中没有找到它,有没有提到它?谢谢 @OpenThread SO(和我)的几个提问者仅在模拟器上遇到了同样的问题。尝试在设备上分析您的应用,如果它没有泄漏,请不要担心。 【参考方案1】:我正在使用AVAudioPlayer
播放文件中的音频,发现iOS 模拟器一直在泄漏内存,但设备没有。这已使用 Instruments 进行了验证。这是 ARC 代码。
我的播放器是这样声明的:
@property (nonatomic, retain) AVAudioPlayer *numberPlayer;
并像这样合成:
@synthesize numberPlayer = _numberPlayer;
由于我需要播放几种不同的声音,而 AVAudioPlayer
在创建后无法重置以播放不同的音频文件,所以我每次都创建一个新播放器,如下所示:
NSString *audioFilePathName = [NSString stringWithFormat:@"Voices/%@/%03i.m4a", self.voiceName, self.theNumber];
NSURL *url = [NSURL fileURLWithPath:BUNDLE_FULL_PATH(audioFilePathName)];
self.numberPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
self.numberPlayer.numberOfLoops = 0;
[self.numberPlayer setCurrentTime:0.0];
[self.numberPlayer setDelegate:self];
[self.numberPlayer prepareToPlay];
[self.numberPlayer play];
在我的委托中,我将播放器设置为nil
,当它播放完毕时:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
if (player == self.numberPlayer)
_numberPlayer = nil;
在模拟器中,AudioSessionDevice
和 UISoundNewDevice
都会泄漏内存。然而,最大的泄密者实际上是NSURL
。这些泄漏都不会在设备上发生。这种行为在 iOS 6 中没有改变,但我确实将我的项目部署设置为 5.0,如果这有什么不同的话。
另请参阅https://***.com/questions/3433487/avaudioplayer-leak-in-simulator 和 memory leak in AudioToolbox library AVAudioPlayer。
【讨论】:
initWithContentsOfURL: 节省兆字节的内存,只有 initWithData: 泄漏兆字节。我将在我的项目中将 initWithData 替换为 initWithContentOfURL。谢谢:)【参考方案2】:也许你做得比我好,而我前面没有 XCode,但是:
对象创建,引用创建:
AVAudioPlayer *newMusicPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];
是赋值而不是分配,没有保留:
_musicPlayer = newMusicPlayer;
函数playMusicWithMusicData
将释放newMusicPlayer
,当我使用_musicPlayer
时,它会使我在其他函数中的代码崩溃。分析器工具非常烦人,因为我做了一个保留,也许也发布了。
如果你使用的是ios4,那么ARC不是这个项目。
在if分支中:
[_musicPlayer stop];
_musicPlayer = nil;
我会检查_musicPlayer
不为零,但这不会解决您的问题。
不知道它可能在哪里,如果不在 ios 中,它可能会在那里:
如果你改变了委托而不是自我,确实解决了。
_musicPlayer.delegate = self;
到任何其他班级?
【讨论】:
我创建了一个测试项目并粘贴了有问题的代码,它与我的音乐项目有同样的问题,在 iOS6 中泄漏,在 iOS4/5 中正常。我什至没有为 AVAudioPlayer 设置任何委托,这没有什么区别 T___T以上是关于iOS6 中的 AudioToolBox 泄漏?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中的 AudioToolBox - 声音在模拟器中有效,但在我的 iPad 上无效
使用 AudioToolBox 将 Wave 文件保存到 NSFileWrapper
IOS音频1:之采用四种方式播放音频文件AudioToolbox AVFoundation OpenAL AUDIO QUEUE