【问题标题】:MemoryLeak problem in following case以下情况下的内存泄漏问题
【发布时间】:2011-04-29 05:25:56
【问题描述】:

单击播放按钮时出现内存泄漏....

我正在使用“运行和性能工具”下的“泄漏”工具进行测试....在模拟器上

当我第一次点击播放按钮时,我得到了泄漏.....

这是我的代码....

-(IBAction)play
{


    [self setPlayer];
    [self playme];  
}



-(IBAction)stop
{
    [self stopme];
    [self releasePlayer];

}


-(void)setPlayer
{

    NSURL *file = [[NSURL alloc] initFileURLWithPath:
                   [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"shut up.mp3"]];
    NSError *err = nil;
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:&err];

    [file release];
    player.numberOfLoops = -1;
    [player prepareToPlay];
    player.volume=1.0;


}


-(void)playme
{
    if (!isPlaying)
    {
        [player play];
        isPlaying=YES;
    }
}


-(void)stopme
{
    if (isPlaying)
    {
        [player stop];
        isPlaying=NO;
    }
}

-(void)releasePlayer
{
    if(!isPlaying)
    {
        [player release];
        player=nil;
    }
    isPlaying=NO;
}

【问题讨论】:

  • 你不是问了同样的问题吗?

标签: iphone memory-leaks avaudioplayer


【解决方案1】:

我认为,下面的语句是内存泄漏的来源,

player = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:&err];

这是讨论相同问题的 SO 帖子。

AVAudioPlayer memory leak

AVAudioPlayer memory leak

AVAudioPlayer Memory Leak - Media Player Framework

这是博文

AVAudioPlayer Memory Leak

已编辑:

根据博客教程,您的代码必须如下所示。

-(void)setPlayer
{

    NSURL *file = [[NSURL alloc] initFileURLWithPath:
                   [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"shut up.mp3"]];
    NSError *err = nil;

    NSData *data = [NSData dataWithContentsOfFile:file];
    AVAudioPlayer *player = [AVAudioPlayer alloc];    
    if([player initWithData:audioData error:NULL])
     {

        player.numberOfLoops = -1;
        [player prepareToPlay];
        player.volume=1.0;
        [player autorelease];
    } 
    else 
    {
        [player release];
        player = nil;
    }
    [file release];
}

无泄漏版本存储的是alloc返回的指针,而不是initWithData:error:返回的指针。这样,无论发生什么,玩家仍然可以被释放。

【讨论】:

  • @RSS:尝试使用编辑后的代码,如果仍有内存泄漏,请告诉我。
  • 请检查你写的代码......它有太多错误......仍然没有帮助我
  • @RSS : 使用你的代码,实际上这种内存泄漏只发生在模拟器而不是设备中。
  • @RSS :我在下面的 SO 帖子中得到了上述评论...看看stackoverflow.com/questions/2840637/…
  • +1 为您的回答 -----好的,我已经阅读了那篇文章....但是您知道我处于我的应用程序的最后阶段,所以不能冒险....什么你认为.......如果可以的话,请回答这个问题....stackoverflow.com/questions/5828951/…
【解决方案2】:

Jhaliya 的回答中的博文描述了一个泄漏,该泄漏是特定于播放器无法启动音频的情况,例如当它找不到文件时。

您的代码的真正问题是,您只有在用户明确停止音频时才释放播放器。如果音频播放到最后,您将拥有一个 retainCount 为 1 的播放器实例。然后,如果用户再次点击播放,您将创建一个新播放器并将其分配给 player 变量,从而泄漏旧播放器。

对此最简单的解决方案是将player 设为保留属性:

@property(nonatomic,retain)AVAudioPlayer *player;

然后,不用直接赋值给ivar,而是使用mutator设置播放器,如果有的话,会隐式释放之前设置的实例:

[self setPlayer:[[[AVAudioPlayer alloc] initWithContentsOfURL:file error:&err] autorelease];

别忘了在你的 dealloc 中释放它:

-(void)dealloc {
    [player release];
    [super dealloc];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    相关资源
    最近更新 更多