多次播放后AVPlayer崩溃 –

我试图创build一个应用程序,使用AVFoundation从文件播放video。 video显示在一个视图中,通过点击父级表格中的一行来访问。 真正的应用程序将有一个video的每一行,但目前我只使用一个testing。

当在模拟器上运行的应用程序是好的,但在设备上运行(在IOS 5.1下)的video播放好了5倍,然后崩溃以各种方式不可预知的。 通常情况下,video视图会加载,但video本身不会播放,但有时我会在coremedia.remote线程上获得coremedia.remote ,抱怨分配了没有自动释放池的对象。 我已经添加了一个@autoreleasepool块来包装启动AVPlayer的代码,但这似乎没有帮助。

我想知道是否GCD正在主队列上创build多个线程来播放项目,但是它们并没有终止。

所以关键的问题是,如果用户点击video视图中的后退button,我如何清除运行AVPlayer的多余的GCD线程尽可能遵循苹果的AVFoundation文档中提供的示例代码,我添加了一些日志和(如上所述)一个@autoreleasepool块内的一个GCD块 – 除此之外,我没有改变代码。

viewDidLoad方法如下所示:

 -(void)viewDidLoad{ [super viewDidLoad]; NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"TestLapCar2Vid" withExtension:@"m4v"]; AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil]; NSString *tracksKey = @"tracks"; [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler: ^{ dispatch_async(dispatch_get_main_queue(), ^{ @autoreleasepool { NSError *error = nil; AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error]; if(status == AVKeyValueStatusLoaded){ avPlayerItem = [AVPlayerItem playerItemWithAsset:asset]; [avPlayerItem addObserver:self forKeyPath:@"status" options:0 context:&ItemStatusContext]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:avPlayerItem]; avPlayer = [AVPlayer playerWithPlayerItem:avPlayerItem]; [videoView setPlayer:avPlayer]; NSLog(@"Asset loaded"); [avPlayer play]; } else{ NSLog(@"The asset's tracks were not loaded"); } } }); }]; 

}

viewWillDisappear方法是:

 -(void)viewWillDisappear:(BOOL)animated{ NSLog(@"view will disappear called"); [super viewWillDisappear:animated]; dispatch_async(dispatch_get_main_queue(), ^{ [avPlayer pause]; [avPlayerItem removeObserver:self forKeyPath:@"status"]; [[NSNotificationCenter defaultCenter]removeObserver:self]; NSLog(@"Race timeline nav controller has %d sub controllers",self.navigationController.childViewControllers.count); avPlayerItem = nil; avPlayer = nil; videoView = nil; dataStore = nil; pkReader = nil; receivedData = nil; revDial = nil; speedDial = nil; mapView = nil; throttle = nil; NSLog(@"releasing stuff"); }); 

}

今天大部分时间我一直在为此而苦苦挣扎,任何帮助都会受到感谢

您应该先从超级视图中移除,因为它会将保留计数减less一个,ARC将为您处理相关问题。

喜欢这个

 [videoView removeFromSuperview]; [self setVideoView:nil]; 

可能是你离开你的videoView保留在某个地方? 因为如果你这样做,你的avPlayerItem和AVPlayer保持活着,根据这个话题,你提出了4个video驻留在内存的iOS渲染pipe道的限制。

请记住,将var设置为nil并不实际释放基础对象。 所以你的

 videoView = nil; 

可以有零效应。