类似于有关创建和销毁UIImagePickerController实例的已知内存泄漏问题,我发现有关UIViewController类实例的类似问题。使用UIImagePickerController的推荐方法是创建一次实例并在应用程序的生命周期内保留它,尽管这会耗尽您在其他地方可能需要的内存。

我正在处理的情况涉及UIViewController类的2个实例。在启动时,创建第一个实例并将其视图添加到另一个“主”实例。 UIViewController类是MainWindow.xib的一部分。在第一个实例中是“信息”。点击时按钮,切换到UIViewController类的新实例(如果尚未创建)。 “主要” UIViewController使用通常的翻转动画来管理这种切换。基本设置可以在“开始iPhone开发:探索iPhone SDK”中看到。戴夫马克的书。

出现的问题是,一旦出现“信息”,第一次点击按钮,内存被分配给新的第二个UIViewController实例,并且在应用程序结束之前不会释放。由于此信息视图中的元素数量,一旦实例化它将使用大约1MB的内存,并且其视图将添加到超级视图中。任何一致地销毁和重新创建此实例的尝试都会导致内存泄漏,类似于当您尝试对UIImagePickerController类的实例执行相同操作时存在的内存泄漏。我怀疑两个类之间的根本原因是相同的。

我的问题的症结在于,在我允许用户使用相机拍照之前,需要释放尽可能多的内存。然而,一旦用户拍摄了照片并且他们第一次看到所得到的图像,他们就可以点击“信息”。第一个UIViewController实例上存在的按钮。一旦敲击,“主要”按钮就会被敲击。 UIViewController删除现有的UIViewController视图,并将其替换为信息屏幕的视图。信息屏幕具有“后退”信息。用于切换视图的按钮。但是,一旦用户离开信息屏幕并选择使用相机拍摄另一张照片,分配给信息屏幕的内存仍在内存中。

UIImagePickerController类在释放其内部引用和“imagePickerController:didFinishPickingImage”之前处理200万像素图像时临时使用大约15-18MB。代表被召唤。一旦通过信息按钮创建了第二个UIViewController实例,然后用户选择拍摄另一张照片,我就会遇到低内存警报。

在我的情况下,无论是否点击信息按钮,无论您是否一遍又一遍地拍照,记忆技术上都不会泄漏,但是由于iPhone上的后台处理(Safari等)的其他问题,您无法控制,在处理相机等事情时,你必须释放尽可能多的内存。

关于如何干净地创建和销毁UIViewController类的实例以使内存不泄漏的任何建议?

有帮助吗?

解决方案

您是从NIB加载第二个视图控制器吗?如果是这样,您将需要检查是否正确释放了相关内存。

以下是我的项目中典型的基于NIB的视图控制器。

SomeViewController.h

@interface SomeViewController : UIViewController {
    UILabel *someLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *someLabel;

@end

SomeViewController.m

@implementation SomeViewController

@synthesize someLabel;

- (void)dealloc {
    // Release our retained IBOutlets
    self.someLabel = nil;
    [super dealloc];
}

@end

其他提示

减少内存使用量的一种方法是将图像大小调整为您想要的大小(除非您想要320x480图像)。这对我的情况有很大帮助。

您正在谈论的第二个视图控制器是否会发生变化?如果没有,那么最好将它作为单例并使用相同的实例。您可以随时更改viewcontroller使用的值。 本文介绍了如何创建单件对象(用代码)

此处的另一篇文章显示了单身人士课程的使用(虽然不同于你的用例,它将阐明如何使用单身人士)

我建议也为UIImagePickerController创建一个单例对象。

您的所有权链中是否有任何周期?类似的东西:

@interface FirstViewController: UIViewController {
  SecondViewController *secondViewController;
}
@end

@interface SecondViewController: UIViewController {
  FirstViewController *firstViewController;
}
@end

如果在丢弃这些视图控制器时没有明确地中断此循环,它们就会泄漏。

另外,我相信当你不再需要时,你负责释放从nib文件加载的所有顶级对象。

也许您可以在转换到信息视图之前保存图像。保存后,释放图像,然后转换到信息视图。如果用户返回,请从文件夹中加载图像。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top