ios - 使用 ARC 从 NSURL 和 AVAudioPlayer 泄漏

标签 ios memory-leaks instruments nsurl

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

-(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]);
}

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

泄漏的对象:

1.

对象:NSURL

负责图书馆:基金会

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

2.

对象:_NSCFString

负责图书馆:基金会

负责的框架:基金会-[NSURL(NSURL) initFileURLWithPath:]

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

我的问题

什么会导致泄漏? 当我不对代码负责时,如何定位漏洞?

编辑 这是 Instruments cycles View 中的架构: enter image description here 谢谢沙尼

最佳答案

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

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

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

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

enter image description here

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

enter image description here

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

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

这是我的测试代码:

-(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;
}

关于ios - 使用 ARC 从 NSURL 和 AVAudioPlayer 泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12498015/

相关文章:

ios - 使用 iOS swift4 验证 JWT token 的签名

iOS:Objective C 代码如何读取 Swift 中的静态变量?

xcode - 仪器拒绝运行

ios - Xcode iOS 仪器 :

ios - DispatchQueue.concurrentPerform 内存损坏

ios - 我将数组添加到字典中,然后从数组中删除所有对象

Android TextView 与 setMovementMethod 泄漏

ios - 内存问题 : potential leak of an object allocated

java - 最大限度地减少单元测试期间的对象保留

ios - presentViewController 性能低下 - 取决于 presentING Controller 的复杂性?