Aideen
Aideen

Reputation: 31

Could loading nib incorrectly in MonoTouch cause memory leaks?

I am creating my first app using MonoTouch. It is fairly simple app that searches for a code from an sqlite database and brings up various meanings for the code on different views. I've used Interface Builder. My question is regarding the correct way to load the nib file.

My custom table view controllers are constructed as such:

public partial class HAZARDTableViewController : UITableViewController
{
    #region Constructors

    // The IntPtr and initWithCoder constructors are required for items that need 
    // to be able to be created from a xib rather than from managed code

    public HAZARDTableViewController (IntPtr handle) : base (handle)
    {
    }

    [Export ("initWithCoder:")]
    public HAZARDTableViewController (NSCoder coder) : base (coder)
    {
        Initialize ();
    }

    public HAZARDTableViewController ()
    {
        Console.WriteLine("HAZARDTableViewController():Constructor");
        Initialize ();
    }

In the .designer.cs file:

public partial class HAZARDTableViewController : UITableViewController
{
#region Constructors

//The IntPtr and initWithCoder constructors are required for items that need 
// to be able to be created from a xib rather than from managed code

    public HAZARDTableViewController (IntPtr handle) : base (handle)
    {
    }

    [Export ("initWithCoder:")]
    public HAZARDTableViewController (NSCoder coder) : base (coder)
    {
        Initialize ();
    }

    public HAZARDTableViewController () //: base ("HAZARDTableViewController", null)
    {
        Console.WriteLine("HAZARDTableViewController():Constructor");
        Initialize ();
    }

    [MonoTouch.Foundation.Register("HAZARDTableViewController")]
    public partial class HAZARDTableViewController {

    private MonoTouch.UIKit.UIView __mt_view;

    private MonoTouch.UIKit.UITableView __mt_tableView;

    #pragma warning disable 0169
    [MonoTouch.Foundation.Connect("view")]
    private MonoTouch.UIKit.UIView view
    {
        get {
        this.__mt_view = ((MonoTouch.UIKit.UIView)(this.GetNativeField("view")));
        return this.__mt_view;
    }
    set {
        this.__mt_view = value;
        this.SetNativeField("view", value);
    }
    }

    [MonoTouch.Foundation.Connect("tableView")]
    private MonoTouch.UIKit.UITableView tableView {
        get {
            this.__mt_tableView = ((MonoTouch.UIKit.UITableView)(this.GetNativeField("tableView")));
        return this.__mt_tableView;
        }
    set {
            this.__mt_tableView = value;
            this.SetNativeField("tableView", value);
        }
    }

One of the things I am looking at is how the custom table view controllers load the nib files. My understanding is that this constructor should be used:

public HAZARDTableViewController () : base ("HAZARDTableViewController", null)

This results in this exception:

Unhandled Exception: MonoTouch.Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: -[UITableViewController loadView] loaded the "HAZARDTableViewController" nib but didn't get a UITableView.

I've also tried this constructor as suggested by Bryan Costanich in his great tutorials to load the nib synchronously.

MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("HAZARDTableViewController", this, null); ViewDidLoad();

This leads to a null reference exception when the code refers to the TableView in ViewDidLoad. (BTW I have tried using tableView instead of TableView.)

I've also tried this constructor according the Xamarin documenation:

public HAZARDTableViewController (string nibName, NSBundle bundle) : base(nibName, bundle) {
    Initialize();
}

Which results in:

Unhandled Exception: MonoTouch.Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: -[UITableViewController loadView] loaded the "HAZARDTableViewController" nib but didn't get a UITableView.

It works when I just make my own constructor without attempting to load my nib.

public HAZARDTableViewController ()
{
    Console.WriteLine("HAZARDTableViewController():Constructor");
    Initialize ();
}

I don't understand how this works without specifically loading the nib. Why this concerns me is that my app falls over after about 6 or 7 mins of use. I've put it through instruments and it gushes memory. I've cleared lists and searched for loose references. Anyway thats for another question. I'm going through my code with a fine comb and I wonder if I'm not loading my nib file correctly is it possible that it is not releasing the nib resources properly? IB is a bit of a black box to me.

So to summarize I would like to know: 1. What is the correct way of loading the nib? 2. Why are the above attempts not working? 3. Could this be causing memory leaks or am I looking in the wrong place?

Upvotes: 3

Views: 712

Answers (1)

user1246345
user1246345

Reputation: 21

Try changing your base class. I also removed the .xib designer file. Here is my code:

public partial class SearchResultsScreen : UITableViewController
{

    List<NewsArticle> NewsArticles;

    static NSString CellID = new NSString ("MyIdentifier");

    public SearchResultsScreen () : base(UITableViewStyle.Grouped)
    {
    }
}

Upvotes: 1

Related Questions