0

I'm building an app that contains an UITableview. I got tableview to work perfectly now I want to make the cells more specific to my needs. The tableviewcell contains a picture a title, subititle and a releasedate. I thought this was simple to do but i cannot get it to work. I try to follow the example (and the sample) out of wrox Professional iPhone programming monotouch ( pages: 120 and 121) but I cannot get it to work in my case. I tried following this link and this link too, but to no avail. The second i do one thing differently it becomes a problem.

I have some of the following files in my project:

  • RootViewController (UITableViewController)
  • myTableViewCell (UITableViewCell)
  • BasicTableViewSource ( UITableViewSource)

Note: I already had a RootViewController but when I was creating the interface for the cell i've added a partial (for RootViewController) to add the cell into.

Here is my code snippets:

myTableViewCell.xib.designer.cs

// Base type probably should be MonoTouch.UIKit.UIViewController or subclass
[MonoTouch.Foundation.Register("RootViewController")]
public partial class RootViewController {

    private myTableViewCell __mt_Cell;

    #pragma warning disable 0169
    [MonoTouch.Foundation.Connect("Cell")]
    private myTableViewCell Cell {
        get {
            this.__mt_Cell = ((myTableViewCell)(this.GetNativeField("Cell")));
            return this.__mt_Cell;
        }
        set {
            this.__mt_Cell = value;
            this.SetNativeField("Cell", value);
        }
    }
}

// Base type probably should be MonoTouch.UIKit.UITableViewCell or subclass
[MonoTouch.Foundation.Register("myTableViewCell")]
public partial class myTableViewCell {

    private MonoTouch.UIKit.UIImageView __mt_img;

    private MonoTouch.UIKit.UILabel __mt_lblInfo;

    private MonoTouch.UIKit.UILabel __mt_lblReleaseDate;

    private MonoTouch.UIKit.UILabel __mt_lblTitle;

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

    [MonoTouch.Foundation.Connect("lblInfo")]
    private MonoTouch.UIKit.UILabel lblInfo {
        get {
            this.__mt_lblInfo = ((MonoTouch.UIKit.UILabel)(this.GetNativeField("lblInfo")));
            return this.__mt_lblInfo;
        }
        set {
            this.__mt_lblInfo = value;
            this.SetNativeField("lblInfo", value);
        }
    }

    [MonoTouch.Foundation.Connect("lblReleaseDate")]
    private MonoTouch.UIKit.UILabel lblReleaseDate {
        get {
            this.__mt_lblReleaseDate = ((MonoTouch.UIKit.UILabel)(this.GetNativeField("lblReleaseDate")));
            return this.__mt_lblReleaseDate;
        }
        set {
            this.__mt_lblReleaseDate = value;
            this.SetNativeField("lblReleaseDate", value);
        }
    }

    [MonoTouch.Foundation.Connect("lblTitle")]
    private MonoTouch.UIKit.UILabel lblTitle {
        get {
            this.__mt_lblTitle = ((MonoTouch.UIKit.UILabel)(this.GetNativeField("lblTitle")));
            return this.__mt_lblTitle;
        }
        set {
            this.__mt_lblTitle = value;
            this.SetNativeField("lblTitle", value);
        }
    }

BasicTableVIiewSource.cs

        public override UITableViewCell GetCell(UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
        UITableViewCell cell = tableView.DequeueReusableCell(this._cellIdentifier);

        myTableViewCell mycell = null;
        //if (cell == null)
        //{
            mycell = new myTableViewCell();
            //NSBundle.MainBundle.LoadNib("RootViewController", _controller, null);
            //_controller.myTableCell = new myTableViewCell();
            //mycell = _controller.myTableCell;
            //cell = new UITableViewCell(UITableViewCellStyle.Subtitle, this._cellIdentifier);
        //}
        //else
        //{
        //  mycell = (myTableViewCell)cell;
        //}


                TrailerInfo item = this._tableItems[indexPath.Section].items[indexPath.Row];

                mycell.Title = item.Title;
                mycell.Info = "Genre: " + item.genre ;  
                mycell.ReleaseDate = Convert.ToDateTime(item.Releasedate).ToLongDateString();
                mycell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
                if(!string.IsNullOrEmpty(item.ImageURL))
                {
                    mycell.myImage = item.image;

                }

    return mycell;

}

RootViewController.xib.designer.cs

// Base type probably should be MonoTouch.UIKit.UIViewController or subclass
//[MonoTouch.Foundation.Register("RootViewController")]
public partial class RootViewController {

    private MonoTouch.UIKit.UITableView __mt_view;

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

RootViewController.xib

        public override void ViewDidAppear(bool some)
    {
        this.TableView.Source = new BasicTableViewSource(items, this);
    }

As you can see through time i've been changing the code. I'm not sure what exactly is the problem. Lately it keeps telling me that the properties (title, info, releasedate) are null. So i'm assuming that mytableviewcell is not being initiated (or referenced). It feels like the two RootViewControlller partial classes are not working together. Again this is just a hunch i'm simply clueless to what is going wrong. Any help is appreciated.

Community
  • 1
  • 1
Adwen
  • 111
  • 3
  • 11

2 Answers2

1

This looks like a duplicate of Button in ContentView causes crash in MonoTouch runtime. Bug in Monotouch 4.0?

and is also tracked on Xamarin's bugzilla @ http://bugzilla.xamarin.com/show_bug.cgi?id=134

The main issue is that nothing reference the managed 'mycell' returned by GetCell so the GC (garbage collector) can (and does) collect/free it. Everything that is only associated with the cell can also be collected and that will crash, later, when you hit your event handler.

To workaround this keep a reference (e.g. a List<>) of the cells you create. That will ensure the GC cannot collect them and everything inside it will be alive when needed (e.g. event handler).

Community
  • 1
  • 1
poupou
  • 43,413
  • 6
  • 77
  • 174
  • Thnx for the reply. I tried what you advised me but still no success. I'm not sure if i did i correctly. I made a global List of mytableviewcell and with getCell i would refer to specific row. I'm still getting a null reference exception on my labels on the cell. How do i know that they are instantiated? Is there a proper example on how to do this? – Adwen Sep 07 '11 at 04:46
  • They get created each time "mycell = new myTableViewCell();" is called and *can* be collected when the 'mycell' value is returned from the method. – poupou Sep 07 '11 at 11:46
0

It is solved! I think it was some sort of typo. I diligently walked every line of code repeating all the steps from the Wrox book and it works now! So I think that I wrote a name wrong somewhere in IB.

It wasn't aggressive garbage collection after all. but thanks for the suggestion!

Adwen
  • 111
  • 3
  • 11
  • Weird. Be warned that the GC runs *much* more often (by design to catch such bugs) on the simulator than on the device - so it will take more time to "hit" this condition when running on devices (but the issue will still exists). – poupou Sep 07 '11 at 11:47