2

我真的很难在 Objective C 中使用自定义构建的类。我可以让它们很好,但是一旦我使用它们来做一些事情,比如播放视频(使用 MPMoviePlayerController 类),我就会遇到内存分配问题。我已经阅读并重新阅读了苹果自己关于内存管理的文档,我已经阅读了各种在线教程,并且我在这里提出并阅读了很多问题。但是我一次又一次地遇到同样的内存分配问题。

到目前为止,我一直在通过将所有代码移入 AppDelegate 类来解决我的内存问题(我觉得这不是正确的做法,我不想重载我的 AppDelegate 类)。我在 AppDelegate 类中的所有属性的行为都与我预期的一样。

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

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

我一直在尝试解决这个问题,(请参阅我过去的问题),但无论我做什么,我都会遇到 EXC_BAD_ACCESS 问题,通常是因为我声明为强大的属性在我的控制之外被释放,当我不希望它。

问这样一个开放式问题我感觉很糟糕,但我觉得我已经用尽了其他可用的选择。

有人可以从头开始向我展示制作一个使用 MPMoviePlayerController 从网络服务器播放视频的类的正确方法 - 但最重要的是,向我展示如何在任何时候都绝对没有内存问题的情况下做到这一点。没有任何东西会意外释放,当我需要它存在时(即视频仍在播放时),一切都在内存中。

很抱歉提出这个问题,但经过几个月的努力解决这个问题,我不知道我还能做些什么。

提前致谢。

4

1 回答 1

2

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

最重要的部分是将其声明MPMoviePlayerController为自定义视图控制器的属性——或自定义视图控制器中使用的自定义类——而不是显式(或隐式,通过关闭视图控制器等)解除分配自定义类,自定义视图控制器,或者MPMoviePlayerController直到你完成它们。

将所有代码放在应用程序委托中通常不是好的设计。您希望将代码分散开来,使其模块化且易于阅读。

从一个带有 .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: 函数中,初始化您的自定义视图控制器,并声明一个 UINavigationController 初始化MyMovieViewController为它的“根视图控制器”:

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

接下来,将应用程序窗口的根视图控制器设置为此 UINavigationController。声明一个用你的 ViewController 初始化的 UINavigationController 作为它的“根视图控制器”。应用程序委托函数的最后一行仍应为:

[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 文件中实现

在 -(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];

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

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

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

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

由于您在 AppDelegate 中添加为根视图控制器,因此该属性mpController将在MyMovieViewController程序的生命周期中存在。如果您想呈现和关闭,每次都重新加载电影,您应该在关闭时设置 = nil。MyMovieViewControllerUINavigationControllerMyMovieViewControllermpController

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

这是一个示例项目,演示MPMoviePlayerController了自定义视图控制器的属性。(注意,这个项目还有一个视图控制器,用于显示和关闭包含 的视图控制器MPMoviePlayerController。为确保正确释放内存,请使用 Instruments 和 Allocations 工具运行项目。按ViewController、过滤MyMovieViewController,并MPMoviePlayerController查看相关类被分配和释放):

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

于 2013-11-25T23:15:40.803 回答