【问题标题】:Monotouch - UITableview Cell null reference exceptionMonotouch - UITableview 单元格空引用异常
【发布时间】:2011-09-05 17:48:42
【问题描述】:

我正在构建一个包含 UITableview 的应用程序。我让 tableview 可以完美地工作,现在我想让单元格更符合我的需求。 tableviewcell 包含图片、标题、副标题和发布日期。我认为这很简单,但我无法让它工作。我尝试按照 wrox Professional iPhone 编程 monotouch(第 120 和 121 页)中的示例(和示例),但我无法让它在我的情况下工作。我也尝试关注此link 和此link,但无济于事。 第二个我做一件事的方式不同,它就会成为一个问题。

我的项目中有以下一些文件:

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

注意:我已经有一个 RootViewController,但是当我为单元格创建界面时,我添加了一个部分(用于 RootViewController)来添加单元格。

这是我的代码 sn-ps:

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);
    }

正如您所见,我一直在更改代码。我不确定到底是什么问题。最近它一直告诉我属性(标题、信息、发布日期)为空。所以我假设 mytableviewcell 没有被启动(或引用)。感觉这两个 RootViewController 部分类没有一起工作。同样,这只是一种预感,我根本不知道出了什么问题。任何帮助表示赞赏。

【问题讨论】:

    标签: ios uitableview mono garbage-collection xamarin.ios


    【解决方案1】:

    这看起来像是 Button in ContentView causes crash in MonoTouch runtime. Bug in Monotouch 4.0? 的副本

    并且还在 Xamarin 的 bugzilla @http://bugzilla.xamarin.com/show_bug.cgi?id=134 上进行跟踪

    主要问题是没有引用 GetCell 返回的 ma​​naged 'mycell',因此 GC(垃圾收集器)可以(并且确实)收集/释放它。也可以收集仅与单元格相关联的所有内容,并且稍后会在您点击事件处理程序时崩溃。

    要解决此问题,请保留您创建的单元格的引用(例如列表)。这将确保 GC 无法收集它们,并且其中的所有内容在需要时都会处于活动状态(例如事件处理程序)。

    【讨论】:

    • 感谢您的回复。我尝试了您的建议,但仍然没有成功。我不确定我是否做对了。我创建了一个全局列表 mytableviewcell 并使用 getCell 我将引用特定行。我的单元格标签上仍然出现空引用异常。我怎么知道它们被实例化了?有没有合适的例子说明如何做到这一点?
    • 它们每次都会被创建 "mycell = new myTableViewCell();"当方法返回 'mycell' 值时,调用并可以被收集。
    【解决方案2】:

    解决了!我认为这是某种错字。我孜孜不倦地遍历每一行代码,重复 Wrox 书中的所有步骤,现在它可以工作了!所以我认为我在 IB 的某个地方写错了一个名字。

    毕竟这不是激进的垃圾收集。不过谢谢你的建议!

    【讨论】:

    • 很奇怪。请注意,GC 在模拟器上运行的频率更多(通过设计来捕获此类错误)而不是在设备上 - 因此在设备上运行时“命中”这种情况需要更多时间(但问题仍然存在)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    相关资源
    最近更新 更多