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

Posted

技术标签:

【中文标题】在 NSTimer 中播放 AVAudioPlayer,没有内存泄漏?【英文标题】:Play AVAudioPlayer in an NSTimer, without memory leak? 【发布时间】:2012-01-03 17:53:16 【问题描述】:

这对我来说是一个长期存在的问题,我一直无法解决。 我正在尝试播放一系列小音频文件。但是,如果我不释放 AVAudioPlayer,我会出现内存泄漏,如果我释放它,则文件根本无法播放。

我试过自动释放,但没有任何效果。

- (void) playSoundShowLabel:(NSTimer*)theTimer 

    NSMutableDictionary *dict = [[[NSMutableDictionary alloc] 
         initWithDictionary:[theTimer userInfo]] autorelease];

    NSURL *clickURL = [NSURL fileURLWithPath:[NSString 
         stringWithFormat:@"%@/%@.mp3", [[NSBundle mainBundle] resourcePath], 
         [dict valueForKey:@"sWav"]]];  

    AVAudioPlayer *theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:
         clickURL error:nil];

    [theAudio play];
    theAudio.numberOfLoops = 0;
    //[theAudio release]; << stops play

我尝试了其他方法来播放带有系统声音的文件,但我遇到了其他问题,所以我确实需要使用AVAudioPlayer

我用谷歌搜索了这个但没有找到答案:(

【问题讨论】:

【参考方案1】:

为播放器使用一个实例变量,并确保它在音频完成或应该被中止之前保持有效。

对于前者,使用它的委托 - 对于后者,使用 viewDidUnload 或 dealloc。

目前,我假设您没有使用 ARC...

在你的接口声明中:

@interface HoldingThePlayerSomeViewController : UIViewController <AVAudioPlayerDelegate>

    AVAudioPlayer *theAudio;

在你的类实现中:

- (void) playSoundShowLabel:(NSTimer*)theTimer 

    NSMutableDictionary *dict = [[[NSMutableDictionary alloc] 
         initWithDictionary:[theTimer userInfo]] autorelease];

    NSURL *clickURL = [NSURL fileURLWithPath:[NSString 
         stringWithFormat:@"%@/%@.mp3", [[NSBundle mainBundle] resourcePath], 
         [dict valueForKey:@"sWav"]]];  

    [theAudio release];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:
         clickURL error:nil];
    theAudio.delegate = self;

    [theAudio play];
    theAudio.numberOfLoops = 0;


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

    if (player == theAudio)
    
        [theAudio release];
        theAudio = nil;
    


- (void)dealloc

    [theAudio release];
    [super dealloc];

【讨论】:

【参考方案2】:

您需要创建一个 AVAudioPlayerDelegate 以便在播放完成时回调。在那里你可以释放你的 AVAudioPlayer。

【讨论】:

以上是关于在 NSTimer 中播放 AVAudioPlayer,没有内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何让 NSTimer 在 iOS 中为我​​的音频播放器在后台运行

ios nstimer 在后台运行以检查警报时间是不是等于当前时间并播放音频

iPhone播放声音时如何操作?

IOS Audio - 加快音乐播放速度

进入后台状态时是不是可以在 iOS 4 设备上运行 NSThread 或 NSTimer?

如何停止 NSTimer