Memory consumption of UINavigationController

Currently we are working on an iPad application (using Monotouch) showing a lot of large images and text. The text is delivered by a webservice as html-strings and we are using UIWebView to show that content on the iPad. Nothing out of the ordinary yet.

But, it turns out the UIWebView control does need a lot of resources to show pages. Especially if there are (large) images in the page, memory consumption is way out there. The iPad cannot handle that and the application crashes quite often loading large pages.

So, I went on a quest to find memory. I learned a couple of good things to know.

1) Remove all references to objects in a view. That sounds pretty obvious (and it is) but if you find that memory consumption is increasing, go start to find the places where references to (child objects of) your UIViewControllers aren't properly released.

2) I found that if you use UINavigationController there are some timing issues for releasing views. If you push a view to the controller, go back using the back button, the pushed view isn't released but after pushing a new view to the controller. That means that at some point you might have two views in memory and that might be just too much for the iPad (as it was in my case)

Issue #1 was soon fixed. Once I found the forgotten reference the object was released. But, due to the rule I found as mentioned in issue 2, the release of memory was too late for my sake.

Suppose you have a pushed view to the navigation controller. If you push the Back button, the controller will call the ViewDidDisappear method of the view and no longer references it. I concluded that because the NavigationController property of the view was nil at the time of the ViewDidDisappear-call. At the ViewWillDisappear call it did have a reference to the navigation controller.

I'm assuming here that after calling the ViewDidDisapper method, the navigation controller is done with the view. And I am concluding here that it is ok for me to call Dispose from the ViewDidDisapper method and release the memory the view consumes.

After quite some testing I didn't find any problems with this approach. It might be that an update to this post will come later telling you that this is a very wrong way of dealing with this issue, but so far it gives me back the memory I so desperately need for the app sooner than it normally does.

If you find any problems with this, please let me know.

Note: I could put up some code here showing how this is done, but you wouldn't need more than the code below :-)

Code Snippet

  1. Public override void ViewDidDisappear(bool animated)
  2. {
  3.     base.ViewDidDisappear(animated);
  4.     Dispose();
  5. }

Hope this helps someone sometime.

Bye,

Bart