我真的很难在Objective C中使用自定义构建的类。我可以使它们很好,但是一旦我使用它们来播放视频(使用MPMoviePlayerController类),我就会遇到内存分配问题。我已经阅读并重新阅读了memory management上的Apples自己的文档,我已经浏览了各种online tutorials,我已经在这里询问并阅读了很多问题。但我一次又一次地得到相同的内存分配问题。
到目前为止,我一直在通过将所有代码移动到AppDelegate类来解决我的内存问题(我觉得这不是正确的事情,我不想重载我的AppDelegate类)。 AppDelegate类中的所有属性都像我期望的那样。
但是一旦我构建了一个自己的类来处理特定任务,一些属性就会被意外释放(我的所有属性都被声明为强大,但它们在使用时仍然被释放)。例如,在播放视频时,播放视频的对象的属性会被释放。我不明白这是怎么发生的。
我觉得我在做一些根本错误的事情。
我一直试图解决这个问题已经有一段时间了(请参阅我过去的问题),但无论我做什么,我都会遇到EXC_BAD_ACCESS问题,通常是因为我声称强大的属性会被释放出来控制,当我不想要它时。
我对提出这样一个开放式问题感到很难过,但我觉得我已经筋疲力尽了其他选择。
有人可以从头开始向我展示使用MPMoviePlayerController从网络服务器播放视频的正确方法吗 - 但最重要的是,告诉我如何在绝对没有内存问题的情况下,在任何时候。什么都没有被意外释放,当我需要它时,一切都在内存中(即视频还在播放时)。
我很遗憾地提出这个问题,但经过几个月的努力,我不知道还能做些什么。
提前致谢。
答案 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}},ViewController
和MyMovieViewController
以查看相关类已分配和取消分配):