Reputation: 5780
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.
Upvotes: 3
Views: 1809
Reputation: 5780
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.
Upvotes: 3