我已经多次使用本教程:http://www.alexyork.net/blog/2011/07/18/creating-custom-uitableviewcells-with-monotouch-the-correct-way/

但是里面有一段代码我不太明白:

    cell = new MyCustomCell();
    var views = NSBundle.MainBundle.LoadNib("MyCustomCell", cell, null);
    cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell;

我试图删除它 - 将 LoadNib 放在构造函数中 - 但这已经出错了,只是 socket 没有正确连接。

任何人都可以对这里发生的事情有所了解吗?为什么我不能在构造函数中加载这个 Nib 文件?为什么需要实际创建两个单元格实例?后台实际发生了什么?代码可以改进吗?

有兴趣了解这一点,因为我经常这样做,我很想使过程更清洁

斯图尔特

如果有帮助,示例单元格是:https://github.com/slodge/MvvmCrossConference/blob/master/Cirrious.Conference.UI.Touch/Cells/SessionCell2.cs

最佳答案

让我们一次一个地看。

LoadNib 方法解压缩(并实例化)NIB 的内容。第一个参数是 NIB 的名称,第二个参数是将加载的 NIB 的所有者。也就是说,NIB 的“文件所有者”占位符对象,在这种情况下,我认为它只是一个 NSObject。

LoadNib 方法还返回一个 NSArray 对象。这些对象是 NIB 的顶级对象,在本例中,它是您在 NIB 中创建的自定义单元格。

我想当你在构造函数中移动上面的代码时,你实现了这样的东西:

public MyCustomCell() : base()
{
    NSBundle.MainBundle.LoadNib("MyCustomCell", this, null);
}

如果不这样做,并且您的实现不同,但您仍在构造函数中使用 LoadNib,则仍然无法保留 socket 。它们被创建得很好,但它们没有被保留。启动的不是 MonoTouch GC 或其他任何东西,而是自动发布的 native 导出。您可能想知道“但是为什么我可以在 UIViewController 的构造函数中使用 LoadNib 并且仍然获得我的导出?”。没错,您可以在 UIViewController 的构造函数中使用 LoadNib,但有一个重要区别: UIViewController 是您的 File's Owner Placeholder 对象。如果您尝试对不是文件所有者的 Controller 执行相同操作,则会在保留 socket 方面遇到同样的失败。

LoadNib 方法基本上需要的是顶级对象的返回数组。因此,要使其在构造函​​数中工作,“正确”的方法是:
    public MyCustomCell() : base()
    {
        NSArray arr = NSBundle.LoadNib("MyCustomCell", this, null);
        this = Runtime.GetNSObject(arr.ValueAt(0)); // should retain everything,
        //BUT: Compile error!
    }

这基本上与您在构造函数之外加载 NIB 所做的事情相同。但当然,我们不能做“这=某事”。因此,总结一下 LoadNib 的创建:您的“MyCustomCell”是一个顶级对象,它通过 LoadNib 的返回值提供给我们,而不是通过将其作为所有者传递。

您正确注意到的下一件事是关于这两个实例:我认为这也是错误的。看一下上面的代码,并附上一些注释:
 cell = new MyCustomCell(); // Created a new instance of MyCustomCell
 var views = NSBundle.MainBundle.LoadNib("MyCustomCell", cell, null); // Assigned it as an owner
 cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell; // What happens to the owner?

我认为这是内存泄漏。但请考虑以下事项:
// Not needed
//cell = new MyCustomCell();
var views = NSBundle.MainBundle.LoadNib("MyCustomCell", tableView, null); // Owner is now the tableView
cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell;
views = null; // Don't need it anymore

NIB 的所有者现在是表 View 。表 View 将由运行时处理(至少在大多数情况下)。

如果您仍然想在 MyCustomCell 类中使用 LoadNib 来创建实例,只需创建一个静态方法:
// Inside MyCustomCell
public static MyCustomCell CreateCell(NSObject owner)
{
    NSArray topLevelObjects = NSBundle.MainBundle.LoadNib("MyCustomCell", owner, null);
    MyCustomCell customCell = Runtime.GetNSObject(topLevelObjects.ValueAt(0)) as MyCustomCell;
    topLevelObjects = null;
    return customCell;
}

有关 NIB 加载的更多信息:

Can you NIB it?

Apple's Resource Programming Guide on NIB files

我希望这有帮助。

关于uitableview - 理解自定义UITableCellView的创建——从MonoTouch中的Nibs加载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9872655/

10-10 05:22