使用 ARC 从 NSURL 和 AVAudioPlayer 泄漏 [英] Leak from NSURL and AVAudioPlayer using ARC

查看:22
本文介绍了使用 ARC 从 NSURL 和 AVAudioPlayer 泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 iPhone 4S 上运行 Instruments.我在这个方法中使用了 AVAudioPlayer:

I am runung Instruments on an iPhone 4S. I am using AVAudioPlayer inside this method:

-(void)playSound{
    NSURL *url = [self.word soundURL];
    NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    if (!error) {
        [audioPlayer prepareToPlay];
        [audioPlayer play];
    }else{
       NSLog(@"Problem With audioPlayer on general card. error : %@ | url %@",[error description],[url absoluteString]);
}

播放声音文件时出现泄漏:

I am getting leaks when playing the sound files:

泄露的对象:

1.

对象:NSURL

责任图书馆:基金会

负责框架:基础 -[NSURL(NSURL) allocWithZone:]

Responsable Frame: Foundation -[NSURL(NSURL) allocWithZone:]

2.

对象:_NSCFString

Object: _NSCFString

责任图书馆:基金会

负责框架:基础 -[NSURL(NSURL) initFileURLWithPath:]

Responsable Frame: Foundation -[NSURL(NSURL) initFileURLWithPath:]

Instruments 没有直接指向我的代码,所以我很难找到泄漏的原因.

Instruments does not point directly to my code so I find it hard to locate the leak reason.

我的问题

什么可能导致泄漏?OR当我对代码不负责时如何定位泄漏?

What could cause the leak? OR How can I locate leaks when I am not responsible to the code?

编辑这是 Instruments 周期视图中的架构:谢谢夏妮

EDIT This is the schema from Instruments cycles view: Thanks Shani

推荐答案

看起来是 Apple 代码中的漏洞...我尝试同时使用两者

Looks to be a leak in Apple's code... I tried using both

  • -[AVAudioPlayer initWithData:error:]
  • -[AVAudioPlayer initWithContentsOfURL:error:]

在第一种情况下,分配的 AVAudioPlayer 实例保留了传入的 NSData.第二种,保留传入的NSURL:

In the first case, the allocated AVAudioPlayer instance retains the passed in NSData. In the second, the passed in NSURL is retained:

我附上了 Instruments 窗口的一些屏幕截图,显示了传入的 NSData 对象的保留/释放历史记录.

I've attached some screen shots of the Instruments window showing the retain/release history for a passed in NSData object.

你可以看到AVAudioPlayer对象然后创建了一个C++对象AVAudioPlayerCpp,它再次保留了NSData:

You can see the AVAudioPlayer object then creates a C++ object AVAudioPlayerCpp, which retains the NSData again:

稍后,当 AVAudioPlayer 对象被释放时,NSData 也被释放,但从来没有来自关联的 AVAudioPlayerCpp 的释放调用..(你可以从附图中看出)

Later, when the AVAudioPlayer object is released, the NSData is released, but there's never a release call from the associated AVAudioPlayerCpp... (You can tell from the attached image)

如果您想避免泄漏 NSData/NSURL,似乎您必须使用不同的解决方案来播放媒体..

Seems you'll have to use a different solution to play media if you want to avoid leaking NSData/NSURL's..

这是我的测试代码:

-(void)timerFired:(NSTimer*)timer
{
    NSString * path = [[ NSBundle mainBundle ] pathForResource:@"song" ofType:@"mp3" ] ;

    NSError * error = nil ;
    NSData * data = [ NSData dataWithContentsOfFile:path options:NSDataReadingMapped error:&error ] ;
    if ( !data )
    {
        if ( error ) { @throw error ; }
    }

    AVAudioPlayer * audioPlayer = data ? [[AVAudioPlayer alloc] initWithData:data error:&error ] : nil ;
    if ( !audioPlayer )
    {
        if ( error ) { @throw error ; }
    }

    if ( audioPlayer )
    {
        [audioPlayer play];
        [ NSThread sleepForTimeInterval:0.75 ] ;
        [ audioPlayer stop ] ;
    }
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...
    [ NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector( timerFired: ) userInfo:nil repeats:YES ] ;
    // ...
    return YES;
}

这篇关于使用 ARC 从 NSURL 和 AVAudioPlayer 泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆