如何创建一个使用MPMoviePlayerController从Web服务器播放视频的类,没有任何内存问题

时间:2013-11-11 10:19:52

标签: ios objective-c cocoa

我真的很难在Objective C中使用自定义构建的类。我可以使它们很好,但是一旦我使用它们来播放视频(使用MPMoviePlayerController类),我就会遇到内存分配问题。我已经阅读并重新阅读了memory management上的Apples自己的文档,我已经浏览了各种online tutorials,我已经在这里询问并阅读了很多问题。但我一次又一次地得到相同的内存分配问题。

到目前为止,我一直在通过将所有代码移动到AppDelegate类来解决我的内存问题(我觉得这不是正确的事情,我不想重载我的AppDelegate类)。 AppDelegate类中的所有属性都像我期望的那样。

但是一旦我构建了一个自己的类来处理特定任务,一些属性就会被意外释放(我的所有属性都被声明为强大,但它们在使用时仍然被释放)。例如,在播放视频时,播放视频的对象的属性会被释放。我不明白这是怎么发生的。

我觉得我在做一些根本错误的事情。

我一直试图解决这个问题已经有一段时间了(请参阅我过去的问题),但无论我做什么,我都会遇到EXC_BAD_ACCESS问题,通常是因为我声称强大的属性会被释放出来控制,当我不想要它时。

我对提出这样一个开放式问题感到很难过,但我觉得我已经筋疲力尽了其他选择。

有人可以从头开始向我展示使用MPMoviePlayerController从网络服务器播放视频的正确方法吗 - 但最重要的是,告诉我如何在绝对没有内存问题的情况下,在任何时候。什么都没有被意外释放,当我需要它时,一切都在内存中(即视频还在播放时)。

我很遗憾地提出这个问题,但经过几个月的努力,我不知道还能做些什么。

提前致谢。

1 个答案:

答案 0 :(得分:2)

要正确使用MPMoviePlayerController,您需要决定何时播放视频,如何处理显示和隐藏电影播放器​​,以及何时需要显示内容。我将在最后用一个示例项目解释一种方法(向下滚动下载链接)。您可以根据自己的喜好随意使用和修改项目。

最重要的部分是将MPMoviePlayerController声明为自定义视图控制器的属性 - 或自定义视图控制器中使用的自定义类 - 而不是显式(或隐式地,通过解除视图控制器等,取消分配自定义类,自定义视图控制器或MPMoviePlayerController,直到完成它们为止。

将所有代码放在app委托中通常不是好设计。您希望将代码扩展到模块化且易于阅读。

从一个带有它的.xib的基本XCode项目开始。然后创建一个自定义视图控制器(.h用于接口,.m用于实现,.xib文件用于用户界面),方法是转到File > New > File,从左侧选择Cocoa Touch,然后选择Objective-C类。单击“下一步”,然后将文件命名为MyMovieViewController。选中“使用XIB获取用户界面”框。

现在,修改您的App Delegate:

在AppDelegate.h中,为自定义视图控制器添加属性:

@property (nonatomic, strong) MyMovieViewController
    *myMovieViewController;

在AppDelegate.m的-​​application:didFinishLaunchingWithOptions:function中,初始化自定义视图控制器,并声明用MyMovieViewController初始化的UINavigationController作为其“根视图控制器”:

self.myMovieViewController = [MyMovieViewController alloc] initWithNibName:@"MyMovieViewController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myMovieViewController];
        self.window.rootViewController = nav;

接下来,将应用程序窗口的根视图控制器设置为此UINavigationController。将使用ViewController初始化的UINavigationController声明为其“根视图控制器”。 app delegate函数的最后一行仍应显示为:

[self.window makeKeyAndVisible];

现在,好的东西。您现在拥有自定义视图控制器MyMovieViewController

MyMovieViewController.h中,将MPMoviePlayerController称为mpController作为属性:

@property (nonatomic, strong) MPMoviePlayerController *mpController;

MyMovieViewController.m的viewDidLoad函数中,实例化mpController

NSString *urlString =@"...";  //your url here
NSURL *url = [NSURL URLWithString:urlString];
self.mpController = [[MPMoviePlayerController alloc] initWithContentURL:url];

MyMovieViewController的xib中创建两个按钮,并将它们链接到 - (IBAction)showControllerButtonPressed:(id)sender和 - (IBAction)hideControllerButtonPressed:(id)sender,都在.m文件中实现< / p>

In - (IBAction)showControllerButtonPressed:(id)sender,添加以下内容:

self.mpController.view.frame = CGRectMake(0,0,320,320); //your size here
[self.view addSubview:self.mpController.view];
[self.mpController prepareToPlay];
[self.mpController play];

设置正确的大小,将控制器的视图添加为自定义视图控制器视图的子视图,准备电影并播放。

In - (IBAction)hideControllerButtonPressed:(id)sender,添加以下内容:

[self.mpController pause];
[self.mpController.view removeFromSuperview];

这会暂停视频(因此音频和视频停止播放)并从自定义视图控制器的视图中删除控制器的视图。

由于您在AppDelegate中添加了mpController作为MyMovieViewController的根视图控制器,因此属性MyMovieViewController将在UINavigationController中生效。如果您想要提交和解除MyMovieViewController,每次重新加载电影,您应该在解雇时设置mpController = nil。

请注意,当视图出现,消失,背景等等时,您也可以告诉mpController暂停和播放。

以下是一个示例项目,将MPMoviePlayerController演示为自定义视图控制器的属性。 (注意,此项目还有一个视图控制器,用于显示和关闭包含MPMoviePlayerController的视图控制器。要确保正确释放内存,请使用Instruments,使用Allocations工具运行项目。筛选依据{ {1}},ViewControllerMyMovieViewController以查看相关类已分配和取消分配):

http://www.filedropper.com/examplemovie-xcode5-ios7