Ios 启用arc的AVAudioPlayer中存在内存泄漏

Ios 启用arc的AVAudioPlayer中存在内存泄漏,ios,memory-leaks,automatic-ref-counting,avaudioplayer,instruments,Ios,Memory Leaks,Automatic Ref Counting,Avaudioplayer,Instruments,ARC已启用。仪器显示内存泄漏。 有解决办法吗 这是我的密码: -(无效)打开播放按钮单击 { NSString*标题=@“暂停”; 如果(iPlay){ [玩家停止]; player.delegate=nil; 标题=@“播放”; } 其他的 { player=[[ReaderGlobals audioPlayer]initWithContentsOfURL:mSoundPath错误:nil]; player.delegate=self; [玩家游戏]; } isPlay^=真; [mButt

ARC已启用。仪器显示内存泄漏。 有解决办法吗

这是我的密码:

-(无效)打开播放按钮单击
{
NSString*标题=@“暂停”;
如果(iPlay){
[玩家停止];
player.delegate=nil;
标题=@“播放”;
}
其他的
{
player=[[ReaderGlobals audioPlayer]initWithContentsOfURL:mSoundPath错误:nil];
player.delegate=self;
[玩家游戏];
}
isPlay^=真;
[mButtonPlay setTitle:状态的标题:UIControlStateNormal];
}

ReaderGlobals
是一个单例类,并且
[ReaderGlobals audioPlayer]
返回
AVAudioPlayer
的单个实例。如果您的单例
[ReaderGlobals audioPlayer]
正在返回一个实例,则不需要调用
initWithContentsOfURL:error:
。也就是说,您告诉我们,
AVAudioPlayer
已经分配(retainCount增加到1)并“初始化”。因此,您应该只设置需要在现有返回实例上设置的内容。不要再调用init

作为一般的最佳实践,您不应该对对象多次调用init。虽然它不会增加重新计数(alloc会增加),但它可能会重新创建/重置内部IVAR,这可能会导致现有值泄漏


一般来说,您应该使用setter将任何值重置为新值(在您的示例中为URL)。但是,
AVAudioPlayer
没有URL的setter,因此无论何时您希望应用不同的URL,都必须创建一个新的
AVAudioPlayer
实例。这就是它的用途。

每次ypu按下播放按钮时都会创建播放器实例。但它并没有发布。使玩家成为财产。停止后,玩家做什么

self.player = nil;
这将在您每次停止时释放玩家azuming玩家对象是一个重量较轻的对象