繁体   English   中英

内存泄漏:AVplayerViewController

[英]Memory Leak: AVplayerViewController

当我们播放视频并返回父窗口时,我正面临内存泄漏。 请参阅下面的分配工具读数截图。 在此输入图像描述 每当我弹出视图控制器(显示视频)时,都会有一些与AVFoundation相关的对象保持内存。 有趣的是,所有这些对象的负责库都是AVFoundation。 内存增加都不是由于APP中创建的对象造成的。 这种流行框架存在一些问题的可能性非常小。 我在网上看到了一些AVPlayerViewController的例子,但它们似乎有同样的问题。

有谁知道问题是什么/在哪里? 如果有人想要复制这个,那么他可以下载上面给出的任何2个项目。 您必须在故事板中进行细微更改,以便使用导航控制器创建根视图控制器。

  • http://www.modejong.com/blog/post13_iOS8_SunSpot/index.html
  • 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];

    }


}

我无法弄清楚这背后的原因。 我尝试使用AVPlayer,并使用(参考Apple AVPlayer演示应用程序。 )创建我自己的UI,我找不到任何泄漏。 它刚刚起作用。 如果有人遇到类似问题,请尝试从AVPlayer演示应用程序中引用代码。 如果有人知道我在这个问题上的问题的答案。 请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM