Look at things one at a time.
The LoadNib method unpacks (and instantiates) the contents of the NIB. The first parameter is the name of the NIB, and the second parameter is the owner of the loaded NIB. That is, the NIB "File Owner" guardian object, which in this case, I suppose, is just NSObject.
The LoadNib method also returns NSArray objects. These objects are top-level NIB objects, which in this case are a user cell created in the NIB.
I assume that when moving the above code in the constructor, you implement something like this:
public MyCustomCell() : base() { NSBundle.MainBundle.LoadNib("MyCustomCell", this, null); }
If you do not, and your implementation is different, but you still use LoadNib in the constructor, the outputs will not be saved anyway. They are created correctly, but they are not saved. This is not a MonoTouch GC that kicks or something else, this is a native output that is auto-implemented. You may be wondering: "But why can I use LoadNib in the UIViewController constructor and still get my weekend?". That's right, you can use LoadNib in the UIViewController constructor, but there is one important difference: UIViewController is the object of your file owner. If you try to do the same with a controller that is not a file owner, you will receive the same failure when saving outlets.
Basically you need the LoadNib method, which is a return array of top-level objects. Therefore, to make it work in the constructor, the โcorrectโ way would be as follows:
public MyCustomCell() : base() { NSArray arr = NSBundle.LoadNib("MyCustomCell", this, null); this = Runtime.GetNSObject(arr.ValueAt(0));
basically this is the same thing you do to load the NIB outside the constructor. But, of course, we cannot "this = something." So, let's summarize with the creation of LoadNib: your "MyCustomCell" is a top-level object, and it is provided to us through the return value of LoadNib, rather than passing it as an owner.
The next thing you noticed correctly is two examples: I believe that this is also wrong. Take a look at your code above, with some comments:
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?
I think this is a memory leak. However, consider the following:
// 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
Now the owner of the NIB is a table view. The table view will be processed by the runtime (in most cases, at least).
If you still want to use LoadNib inside your MyCustomCell class to instantiate, just create a static method:
// 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; }
More on downloading NIB:
Can you nib this?
Apple Resource Programming Guide for NIB Files
Hope this helps.