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

时间:2012-01-03 17:53:16

标签: iphone objective-c ios cocoa-touch avaudioplayer

这对我来说是一个长期存在的问题,我一直无法解决。 我正在尝试播放一系列小音频文件。但是,如果我不释放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

我用谷歌搜索了但未找到答案:(

2 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分:0)

您需要创建一个AVAudioPlayerDelegate,以便在播放完成后进行回叫。在那里你可以解除你的AVAudioPlayer。