iOS 从 nib 加载视图会造成内存泄漏?

Posted

技术标签:

【中文标题】iOS 从 nib 加载视图会造成内存泄漏?【英文标题】:iOS loading a view from nib creates memory leaks? 【发布时间】:2012-01-11 10:01:38 【问题描述】:

我正在尝试从单独的 NOB 文件中加载包含地图视图和 2 个按钮的视图。

编辑:我应该提到我不能继承 UIViewController,因为我不希望视图以标准方式呈现(例如作为模态)。我希望它只使用四分之一的屏幕,透明,并像弹出视图一样呈现。因此,不建议将 UIVIewController 用于不会占据整个屏幕或至少不会作为标准模式视图控制器或 UINavigationController 层次结构的控制器呈现的视图。

不想使用 UIViewController 子类(Apple 说不要这样做),我决定构建一个 ContainerObject,NSObject 的后代,它将处理连接和解除分配。

在容器对象内,我只有 1 个 IBOutlet:(视图)。我在 init 函数中以这种方式加载笔尖:

- (id)init 
self = [super init];
if (self) 
    [[NSBundle mainBundle] loadNibNamed:"myNib" owner:self options:nil];

return self;

在 NIB 内部有一个视图,里面有一个 MapView 和两个按钮。作为文件的所有者,我已经设置了我的 Container 对象的类,并且我已经将“视图”出口连接到了文件所有者的出口。笔尖加载正常,我可以加载它并将其视图添加到我的子视图中。

self.currentLocationMapView = [[[CurrentLocationViewContainer alloc] init] autorelease];
self.currentLocationMapView.delegate = self;
[self.view addSubview:self.currentLocationMapView.view];

问题在于释放,因为虽然容器对象被成功释放,但视图内部并没有释放:

    [self.currentLocationMapView.view removeFromSuperview];
self.currentLocationMapView = nil;

永远不会调用位于容器对象中的自定义视图的 dealloc 消息。我必须显式调用 [self.currentLocationMapView.view release] 以便在需要时释放它。

请注意,“self.currentLocationMapView.view”是我的视图控制器中的容器对象。容器对象包含自定义视图,而自定义视图又包含地图视图和 2 个按钮。

【问题讨论】:

苹果确实说要继承 UIViewController。事实上,如果你创建一个新的 iphone 应用程序。 UIViewController 至少有一个子类。你的 ContainerObject 完成了自定义 UIViewController 的设计工作。 你能指出苹果文档中说不要子类化 UIViewController 吗? @JeanLuc:我知道。但是,我应该说我不想以标准方式呈现我的观点。我想将其呈现为弹出窗口。你可以在这里看到这个人的答案:***.com/a/4973203/737457我没有时间在论坛中搜索它。然而:他是对的。如果您创建了一个自定义视图控制器并且没有按照它应该使用的方式使用它,它就不会收到它必须接收的视图控制器消息,并且它会泄漏内存,因为它会被释放,但不会释放它的视图。 既然我找到了答案,我把它连同更多信息一起发布在下面,这将有助于解决问题。 【参考方案1】:

既然没有人回答这个问题,那我自己来回答吧,因为我找到了解决方案,以及一些其他有用的信息。

我的问题的解决方案是在我的应用程序中发现一个非常难以发现的错误。错误是什么并不重要,它是非常特定于应用程序的,并且不会发生在任何其他应用程序中。

就 UIViewControllers 而言,您不应该使用 UIViewControllers 或子类来使用 Apple 标准方法以外的方法来呈现视图。曾经。如果您想向用户呈现一个不属于视图层次结构(如 UITabBarController、UINavigationController 或类似的东西)的视图,则必须以编程方式执行此操作,而不使用 View Controller 作为此类的管理器对象。您应该使用 NSObject 作为视图的管理器。

这是因为 UIViewController 的内部保留了对视图和其中其他对象的引用,这些引用在调用 UIViewController 的某些方法时被释放。如果不是 Apple 视图层次结构的一部分,这些方法将永远不会被调用,从而造成内存泄漏。

【讨论】:

很好地解释了..我还从视图控制器调用在 XIB 文件中定义的警报视图,这会导致泄漏......我唯一没有得到的是你所说的“你应该使用 NSObject 作为取而代之的是视图的经理。”你能提供一些你是如何呈现视图的代码示例吗?

以上是关于iOS 从 nib 加载视图会造成内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 内存泄漏与 nib

知行合一·固本精益求精——WebSphere 内存泄漏分析技巧

绑定会在 WPF 中造成内存泄漏吗?

OpenGL VBO 会泄漏内存吗?

关于IOS内存泄漏

Facebook 的 iOS 内存泄漏监测自动化实践