Bug 9846 - UIWebViews do not dispose when hosted inside a dialog view controller
Summary: UIWebViews do not dispose when hosted inside a dialog view controller
Status: RESOLVED FEATURE
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 6.0.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-01-29 10:57 UTC by Ray Kelly
Modified: 2013-01-30 04:35 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Example (3.08 KB, application/octet-stream)
2013-01-29 10:57 UTC, Ray Kelly
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FEATURE

Description Ray Kelly 2013-01-29 10:57:58 UTC
Created attachment 3296 [details]
Example

I have a UIViewElement that contains a UIWebView loaded into a Dialog View controller:

DialogViewController
    Root
      Section
         UIViewElement
            UIWebView
         UIViewElement
            UIWebView
         etc......

When I call Section.Clear(), not all UIWebViews are disposed.  This is seen using XCode Instruments Allocations view.   If the UIWebViews are created and not added to the Dialog View, they are disposed of properly.  For some reason this example creates 100 rows, but when cleared, leaves behind 14 instances.   In my real app its usually worse and only disposes of a few UIWebViews.

Attached is an example ViewContoller that reproduces what is described above.
Comment 1 Sebastien Pouliot 2013-01-29 14:51:24 UTC
I'll have a look but I do not think it's a bug. 

1. MonoTouch.Dialog is based on UITableView. It can hide a lot of its complexity but the behaviour will still be identical;

2. UITableView uses UITableViewCell instances. However to minimize them it reuse the cells whenever possible. So a table with 1000 cells, showing only a dozen on the screen, might only need to allocate (no much more than) a dozen cells (not a 1000).

3. Normal (or MT.D) code looks like this:

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell ("cell") as MyCell;
    if (cell == null) {
        // create new cell
        cell = new MyCell ();
    } else {
        // prepare cell for reuse
    }
    // customize cell
    return cell;
}

What's likely happening is that:

* you create 100 elements;
* when asked the element creates the cell, about 14 times to fill the screen, the reuse them;
* section.Clear clears the UI (not the cell cache);
* Instruments shows you what UITableView has allocated (14 cached/reusable cells);
* Those cells will be freed when you dispose the UITableView (which is allocated by the DialogViewController);
Comment 2 Sebastien Pouliot 2013-01-29 19:33:36 UTC
Instruments confirm the above. On an iPad 29 UITableViewCell are created (confirmed by modifying MT.D GetCell code) and that's the number of "final" UIWebView that's left (confirmed by Instruments) once sections are cleared (the other 71 UIWebView were released). UITableView will hold them until all references to it are removed.

Note that MT.D might not be the best choice for loading a lot of `UIViewElement` - because the elements (and the `UIView`) will be created (by your code) even if never shown on screen.

Manually handling the UITableView (a bit more complex, but MT.D source code shows how) would allow you to cache the UIWebView (e.g. having 29 on an iPad instead of 100). OTOH that would save a lot of memory (and initialization time) for your application.
Comment 3 Ray Kelly 2013-01-30 04:35:05 UTC
Thank you Sabastien. I think you are right about manually handling the cells.  Once I get over a few hundred UIWebViews, the GUI gets bogged down on my iPhone 4.   Thanks for the tips.