代码之家  ›  专栏  ›  技术社区  ›  David

iPhone编程:avaudioplayer在播放时泄漏内存

  •  2
  • David  · 技术社区  · 15 年前

    我是新来使用avadioplayer,我似乎有一个记忆当我播放一个声音。 我想不出我缺了什么才能把它扔进仪器里。这可能是假阳性吗?

    视图控制器.h:

    @interface ISpectatorViewController : UIViewController <UIAccelerometerDelegate>{
    
    AVAudioPlayer *massCheerSoundID;
    
    }
    
    @property(nonatomic,retain) AVAudioPlayer * massCheerSoundID;
    

    //视图控制器.m

    - (void)viewDidLoad {
    
        NSString * filePath;
    
        filePath = [[NSBundle mainBundle] pathForResource:@"massCheer" ofType:@"mp3"];
    
        massCheerSoundID = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath ]error:nil];
    
    }
    
    - (void) playSound
    {
    
            if(massCheerSoundID.playing == false)
        {
    
            massCheerSoundID.currentTime = 0.0;
    
    
                    //leak here
            [massCheerSoundID play];
        }
    }
    
    - (void)dealloc {
    
        [super dealloc];
        [massCheerSoundID release];
    
    }
    

    我发现了问题所在。

    我需要在接口上添加AVAudioPlayerDelegate,因为我已经设置了uiaccelerometerelegate

    @interface iSpectatorViewController: UIViewController<AVAudioPlayerDelegate>
    

    并设置

    massCheerSoundId.delegate = self
    
    5 回复  |  直到 15 年前
        1
  •  3
  •   ahmet emrah    15 年前

    尝试将MediaPlayer.framework添加到项目中,但不更改代码

        2
  •  2
  •   shw    15 年前

    今天发现了同样的漏洞。添加MediaPlayer.framework似乎可以解决这个问题。

        3
  •  1
  •   pgb    15 年前

    是你的吗 dealloc 方法?

    我认为大会应该首先 release 然后打电话 [super dealloc] .

    我一直以为这是为了“先发布你的东西,然后让你的父类处理它”。

    你的 释放内存 方法应为:

    - (void)dealloc {
    
        [massCheerSoundID release];
        [super dealloc];
    
    }
    
        4
  •  1
  •   user633465    14 年前

    今天发现了同样的漏洞。添加MediaPlayer.framework似乎可以解决这个问题。

    这对我也有用。很奇怪。

        5
  •  0
  •   Daniel    15 年前

    问题可能是,如果你不删除你的视图,你可能会一遍又一遍地重新启用massCheerSoundId。所以,如果你正在添加你的子视图,viewDidLoad会被调用并且你初始化你的播放器,那么也许你正在删除子视图并再次添加它,因为你没有释放视图(假设你只有一个副本),dealloc不会被调用(我也不这么认为),然后,如果重新添加视图massCheerSoundId将被重写并泄漏..,另一个问题可能是,由于您将massCheerSoundId作为属性,因此您将其分配,并且生成的setter也将保留它,因此当它只应为+1时,您将保留一个+2引用计数…因此,假设我的假设是正确的,我建议您编写像这样加载视图

        - (void)viewDidLoad {    
        NSString * filePath;   
         filePath = [[NSBundle mainBundle] pathForResource:@"massCheer" ofType:@"mp3"]; 
        if(massCharSoundId!=nil)
    {
           AVAudioPlayer *p= [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURLfileURLWithPath:filePath ]error:nil];}
           massCheerSoundID = p;
         [p release];
    }