了解定制UITableCellView的创建 - 在MonoTouch的

问题描述:

从笔尖加载

我用这个教程几次:http://www.alexyork.net/blog/2011/07/18/creating-custom-uitableviewcells-with-monotouch-the-correct-way/了解定制UITableCellView的创建 - 在MonoTouch的

但有代码中有一个节我不明白得好:

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

我试图删除这个 - 将LoadNib放置在构造函数内部 - 但是这种方法出错了,只是没有正确连接。

任何人都可以点亮这里发生的一切吗?为什么我不能在构造函数中加载这个Nib文件?为什么需要实际创建两个单元实例?背景中究竟发生了什么?代码可以改进吗?

兴趣了解这是我做的很频繁,我很乐意使这个过程更清洁

斯图尔特

如果有帮助,一个例子细胞是:https://github.com/slodge/MvvmCrossConference/blob/master/Cirrious.Conference.UI.Touch/Cells/SessionCell2.cs

+1

我试图写一个完整的答案,但我仍然无法。有很多关于它的东西。简而言之:您不需要连接到NIB文件所有者的单元格中的插座,并且您传递给LoadNib(..)的所有者应该声明插座。我目前正在编写一篇关于NIB加载的文章,我相信这个文章很多。在此之前,请查看我创建的示例项目:http://github.com/dtavlikos/JTNibManager – 2012-03-26 18:42:12

+0

谢谢。 W期待博客文章和学习。我很乐意向您介绍sib编辑,但是目前我发现整个过程有点混乱(也可能是越野车) – Stuart 2012-03-26 19:56:38

+0

检查我的答案。 – 2012-03-28 08:33:39

让我们来看看一次处理一件事。

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

LoadNib方法还返回一个NSArray对象。这些对象是NIB的*对象,在这种情况下,它是您在NIB中创建的自定义单元格。

我想,当你在构造函数中移动上面的代码中,你实现这样的事情:

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

如果不这样做,你的实现是不同的,但你仍然在使用构造LoadNib,网点仍然无法保留。他们创造得很好,但他们不被保留。它并不是MonoTouch GC开始或任何东西,它是自动发布的本地插座。你可能会想:“但为什么我可以在UIViewController的构造函数中使用LoadNib,并且仍然可以获得我的网点?”。这是正确的,你可以在UIViewController的构造函数中使用LoadNib,但是有一个重要的区别:UIViewController是你的文件所有者占位符对象。如果您试图对不是文件所有者的控制器执行相同的操作,则在保留插座时会发生同样的故障。

你基本上需要从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的所有者现在是表格视图。表视图将由运行时处理(至少在大多数情况下)。

如果你仍然想使用LoadNib您MyCustomCell类中创建一个实例,只需要创建一个静态方法:

// 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

我希望这会有所帮助。

+0

Dimitri,很好的回答,只是有一个评论。我不确定设置'views = null'或'topLevelObjects = null'是否有帮助。如果它们是局部变量,则不必将它们设置为空 - 它们将会得到GC'ed没有问题。我喜欢你的'你可以不喜欢它吗?'文章,自己一直在想那些东西的内部。 – jonathanpeppers 2012-03-28 11:52:48

+0

嗨乔纳森。你是对的,这只是我最近一直在阅读许多ObjC的东西。至于NIB加载,我正在准备更多的东西,敬请期待...;) – 2012-03-29 07:40:02

+0

是的,我在C#工作了很久,我认为这是理所当然的。我不确定我会在Obj-C世界中制作。 – jonathanpeppers 2012-03-29 11:46:38