iOS 从 nib 加载视图会导致内存泄漏吗?

发布于 2024-12-26 17:58:23 字数 1251 浏览 6 评论 0原文

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

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

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

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

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

}

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

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

问题在于释放,因为当容器对象成功释放时,视图在其内部并未释放:

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

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

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

I am trying to load view that contains a map view and 2 buttons, from inside a separate NOB file.

EDIT: I should have mentioned that I must not subclass a UIViewController, because I don't want the view to be presented the standard way (as a modal for example). I want it to use only a quarter of the screen, be transparent, and be presented like a popup view. Therefore, UIVIewController is NOT advisable for a view that won't take up the entire screen or at least won't be presented as a standard modal view controller or a controller of a UINavigationController hierarchy.

Not wanting to use a UIViewController subclass (Apple says to not do that), I decided to build a ContainerObject, descendant of NSObject, that will handle the connections and deallocations.

Inside the container object I only have 1 IBOutlet: (the view). I load the nib this way inside the init function:

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

}

Inside the NIB there is a view, that has a MapView inside it, and two buttons. As the file's owner I have set the class of my Container object, and the I have connected the "view" outlet to the outlet in the file's owner. The nib load fine, and I am able to load it and add its view to my subview.

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

The problem lies in the deallocation, because while the container object is successfully deallocated, the view is NOT deallocated inside it:

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

The dealloc message of my custom view, which lies in the container object is never called. I must explicitly call [self.currentLocationMapView.view release] in order to have it deallocated when I want it to.

Note that "self.currentLocationMapView.view" is the container object in my view controller. The container object holds the custom view, which in turn holds the map view and the 2 buttons.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月寒剑心 2025-01-02 17:58:23

既然没有人回答这个问题,我不妨自己回答一下,因为我在搜索过程中找到了解决方案以及其他一些有用的信息。

我的问题的解决方案在于我的应用程序中很难找到错误。错误是什么并不重要,它是特定于应用程序的,并且与任何其他应用程序中发生的情况不同。

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

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

Since no one answered the question, I may as well answer it myself, since I found the solution, and some other useful information while searching for it.

The solution to my problem lied into a very difficult to find bug in my application. It doesn't matter what the bug was, it is very application-specific and unlike to happen in any other app.

As far as UIViewControllers are concerned, you should not use UIViewControllers or subclasses to present Views with method other that the Apple's Standard methods. Ever. If you want to present a view to the user which is not part of a view hierarchy like a UITabBarController, or UINavigationController or anything like that, you must do so programmatically without using a View Controller as a manager object of this class. You should use NSObject as the manager of the view instead.

This is because UIViewController's internals keep references to views and other objects inside them, that are released when certain methods of the UIViewController are called. When not part of an Apple view hierarchy, these methods will never get called, thus creating memory leaks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文