当我们播放视频并返回父窗口时,我正面临内存泄漏。请参阅下面的分配工具读数截图。每当我弹出视图控制器(显示视频)时,都会有一些与AVFoundation相关的对象保存内存。 有趣的是,所有这些对象的负责库都是AVFoundation。内存增加都不是由于APP中创建的对象造成的。这种流行框架存在一些问题的可能性非常小。我在网上看到了一些AVPlayerViewController的例子,但它们似乎有同样的问题。
有谁知道问题是什么/哪里?如果有人想要复制这个,那么他可以下载上面给出的任何2个项目。您必须在故事板中进行细微更改,才能使用导航控制器创建根视图控制器。
https://github.com/coolioxlr/PageView-AVPlayer
这就是我清理记忆的方式:
-(void) dealloc{
[self clearCurrentVideo];
}
-(void)clearCurrentVideo {
[_playerItem removeObserver:self forKeyPath:@"status"];
[_currentVideoPlayerViewController.player removeObserver:self forKeyPath:@"rate"];
[_currentVideoPlayerViewController.player pause];
_currentVideoPlayerViewController.delegate=nil;
_currentVideoPlayerViewController.player=nil;
_playerItem=nil;
_currentVideoPlayerViewController = nil;
}
这是我加载视频资源的方式:
-(void)playtheAsset:(AVAsset *)asset{
[asset loadValuesAsynchronouslyForKeys:@[@"playable"] completionHandler:
^{
dispatch_async( dispatch_get_main_queue(),
^{
[self loadTheAsset:asset withKeys:@[@"playable"]];
});
}];
}
- (void)loadTheAsset:(AVAsset *)asset withKeys:(NSArray *)requestedKeys{
/* Make sure that the value of each key has loaded successfully. */
for (NSString *thisKey in requestedKeys)
{
NSError *error = nil;
AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
if (keyStatus == AVKeyValueStatusFailed)
{
//[self assetFailedToPrepareForPlayback:error];
if([thisKey isEqualToString:@"playable"]){
[self showNetworkErrorLabel];
}
return;
} else if ((keyStatus == AVKeyValueStatusLoaded) || ( keyStatus == AVKeyValueStatusLoading )){
[self removeNetworkLabel ];
}
}
/* Use the AVAsset playable property to detect whether the asset can be played. */
if (!asset.playable)
{
/* Generate an error describing the failure. */
NSString *localizedDescription = NSLocalizedString(@"Item cannot be played", @"Item cannot be played description");
NSString *localizedFailureReason = NSLocalizedString(@"The assets tracks were loaded, but could not be made playable.", @"Item cannot be played failure reason");
NSDictionary *errorDict = [NSDictionary dictionaryWithObjectsAndKeys:
localizedDescription, NSLocalizedDescriptionKey,
localizedFailureReason, NSLocalizedFailureReasonErrorKey,
nil];
NSError *assetCannotBePlayedError = [NSError errorWithDomain:@"StitchedStreamPlayer" code:0 userInfo:errorDict];
NSLog(@"%@",assetCannotBePlayedError);
[self showNetworkErrorLabel];
/* Display the error to the user. */
[self assetFailedToPrepareForPlayback:assetCannotBePlayedError];
return;
}
/* At this point we're ready to set up for playback of the asset. */
/* Stop observing our prior AVPlayerItem, if we have one. */
if (_playerItem)
{
/* Remove existing player item key value observers and notifications. */
[_playerItem removeObserver:self forKeyPath:@"status"];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVPlayerItemDidPlayToEndTimeNotification
object:_playerItem];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVPlayerItemPlaybackStalledNotification
object:_playerItem];
}
/* Create a new instance of AVPlayerItem from the now successfully loaded AVAsset. */
_playerItem = [AVPlayerItem playerItemWithAsset:asset];
/* Observe the player item "status" key to determine when it is ready to play. */
[_playerItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerStatusObservationContext];
/* When the player item has played to its end time we'll toggle
the movie controller Pause button to be the Play button */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:_playerItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemFailedToPlayToEndTime:) name:AVPlayerItemPlaybackStalledNotification object:_playerItem];
// Remove the movie player view controller from the "playback did finish" notification observers
// Observe ourselves so we can get it to use the crossfade transition
[[NSNotificationCenter defaultCenter] removeObserver:_currentVideoPlayerViewController
name:kPlayerViewDismissedNotification
object:_currentVideoPlayerViewController.player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(videoFinishedCallback:)
name:kPlayerViewDismissedNotification
object:_currentVideoPlayerViewController.player];
/* Create new player, if we don't already have one. */
if (!_currentVideoPlayerViewController.player)
{
/* Get a new AVPlayer initialized to play the specified player item. */
_currentVideoPlayerViewController.player=[AVPlayer playerWithPlayerItem:self->_playerItem];
[_currentVideoPlayerViewController.player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionNew
context:AVPlayerDemoPlaybackViewControllerRateObservationContext];
}
}
答案 0 :(得分:1)
我无法弄清楚这背后的原因。我尝试使用AVPlayer而使用(引用Apple AVPlayer Demo app.)创建了我自己的UI,我找不到任何泄漏。它刚刚起作用。 如果有人遇到类似问题,请尝试从AVPlayer演示应用程序中引用代码。 如果有人知道我在这个问题上的问题的答案。请告诉我。