使用 ARC 从 NSURL 和 AVAudioPlayer 泄漏 [英] Leak from NSURL and AVAudioPlayer using ARC
问题描述
我在 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屋!