【问题标题】:MPMoviePlayerController still leakingMPMoviePlayerController 仍然泄漏
【发布时间】:2011-03-23 23:59:47
【问题描述】:

我释放了 MPMoviePlayerController 但内存分配和活动对象仍然高于对象分配之前。但是,如果我重新分配对象,它不会泄漏更多。 我的应用程序实际上使用了很多媒体文件并且内存消耗很高。我想完全释放不需要的内存以避免内存警告。

电影播放器​​发布:

        player.initialPlaybackTime = -1;
        [player.view removeFromSuperview];
        [player stop];
        [player release];

电影播放器​​分配:

    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"video0_hd.mov" ofType:nil]];
    player = [[MPMoviePlayerController alloc] initWithContentURL:url];
    player.view.frame = placeholder.frame;
    [self.view addSubview:player.view];
    [player play];

【问题讨论】:

    标签: iphone ios memory-management memory-leaks mpmovieplayercontroller


    【解决方案1】:

    我也有这个问题。

    iPad 用于预加载视频流的缓存没有完全清空。 所以每次清理和释放这个带有视频播放器的页面,清理后分配的内存仍然包含缓存的内存。对于大视频,这可能高达 50 MB。

    这其实不是内存泄漏:

    如果页面被再次打开,缓存被重新分配。但是仍然令人沮丧,因为您想要一个干净的退出情况,这意味着当这个页面被留下并清理时,这个页面使用的所有内存都应该被释放,包括用于缓存视频流的内存......!

    经过一番认真的调整后,这一系列命令似乎可以完成这项工作:

    =======================

        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:myMoviePlayer];        
    
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMoviePlayerDidExitFullscreenNotification
                                                      object:myMoviePlayer];        
    
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMoviePlayerLoadStateDidChangeNotification
                                                      object:myMoviePlayer];
    
        [[NSNotificationCenter defaultCenter] removeObserver:self
                                                        name:MPMovieDurationAvailableNotification
                                                      object:myMoviePlayer];        
        [myMoviePlayer pause];
        myMoviePlayer.initialPlaybackTime = -1;
        [myMoviePlayer stop];
        myMoviePlayer.initialPlaybackTime = -1;
        [myMoviePlayer.view removeFromSuperview];
        [myMoviePlayer release];
    

    ==================================

    分步:

    1 - 删除您用于电影播放器​​的所有通知。

    2 - 暂停电影

    3 - 设置播放时间开始

    4 - 停止电影

    5 - 再次设置播放时间开始

    6 - 现在删除电影视图

    7 - 最后释放电影播放器​​

    在我的情况下,我的 iPad(OS 4.2)上也释放了视频缓存。 并留下一个干净的分配内存情况,等于打开视频播放器的页面之前的大小。所以同样的进入和退出内存。

    希望这会有所帮助......

    【讨论】:

    • 嗨.. 我收到这个错误 _itemFailedToPlayToEnd: { kind = 1;新 = 2;旧 = 0; } ..我尝试了你的代码..但不起作用...有时视频正在播放..有时我在同一视频@ladhani中遇到此错误
    【解决方案2】:

    您是否尝试过构建和分析(构建>构建和分析),这可以向您显示确切的行内存泄漏(如果有)。

    现在,我感觉问题出在你定义 NSURL 的位置。

    【讨论】:

    • 它是一个自动释放对象,问题不存在,这是肯定的。
    • 同意...您只发布您特别指定的内容alloc/init ..其他一切都不是您的责任,特别是如果它是一个便利类。苹果自动发布这些
    【解决方案3】:

    您是在设备上还是在模拟器上运行此代码?模拟器给出了一堆假泄漏(如AudioToolbox、CoreVideo等)。此外,模拟器似乎缓存了整个视频并且没有正确释放它,而设备只缓冲它所需要的。

    我在模拟器上用一个 mp4 视频测试了你的代码,我得到了与你所说的相似的结果(每次播放视频时 10 个活动对象,没有一个死亡......分配了 20mb,即使在发布后还剩下 5mb )。活体对象和内存分配会在模拟器上不断增长。

    但是,在我的 iPhone(带有 20mb 视频)上,它只为应用程序分配了总共 900kb 的内存,在开始/停止/释放视频时没有明显的变化。在我测试它的 10 次(启动/停止/释放)中,它始终保持在 900kb 左右。

    看起来你又一次不能信任模拟器了。

    我正在测试的代码:

    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"SomeMovieFile" ofType:@"mp4"]];
    
    MPMoviePlayerController *newPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
    
    self.player = newPlayer;  
    [newPlayer release];
    
    [self.view addSubview:player.view];  // for my example, I didn't set the frame location, but no difference that would do
    [player play];
    

    然后我在另一个按钮中停止它并释放播放器:

    [player.view removeFromSuperview];    
    player.initialPlaybackTime = -1;
    [player stop];
    self.player = nil;  // this is just a habit of mine.. calling stop should unload the buffers though
    [player release];
    

    【讨论】:

    • 您实际上应该避免使用“player=nil; [player release];”因为您在技术上释放“nil”,不是分配的播放器,这可能会导致泄漏。
    • 其实设置对象为nil会释放对象的旧值,然后将对象值设置为nil。就像任何其他对象一样,您仍然必须明确释放任何东西 alloc / init.. 我认为您对仅将对象设置为 nil 然后不释放它感到困惑。在这种情况下,您正在泄漏对象,因为您仍然有一个指向内存中某个永远不会被释放的对象的指针。
    • 其实这段代码是在iPad上测试过的,内存分配从来没有完全释放。无论如何,如果您测试了您发布的代码并且没有任何内存泄漏,那么您可以在释放对象之前将指针设置为零。
    • 嗯.. 我在 iPhone 4 上进行测试。我听说 iOS 3.2 存在问题,在停止播放器之前必须致电 [player pause];。由于我没有 iPad,我不确定这是否对您有帮助。就像我说的,调用[player stop]; 应该清除数据缓冲区,但我只是习惯于设置为nil 以防万一。它应该以任何一种方式工作。此外,请确保您添加了所有必要的框架(有时会修复奇怪的泄漏)。
    • @IWasRobbed:所有必要的框架?这还不够#import ?
    猜你喜欢
    • 1970-01-01
    • 2011-10-13
    • 2011-04-19
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多