Давайте посмотрим на вещи по одному.
Метод LoadNib разархивирует (и создает экземпляры) содержимое NIB. Первый параметр - это имя NIB, а второй параметр - владелец NIB, который будет загружен. То есть объект-заполнитель NIB "File's Owner", который, в данном случае, я полагаю, является просто объектом NSObject.
Метод LoadNib также возвращает NSArray объектов. Эти объекты являются объектами верхнего уровня NIB, в данном случае это пользовательская ячейка, созданная в NIB.
Полагаю, когда вы перемещаете код выше в конструкторе, вы реализуете что-то вроде этого:
public MyCustomCell() : base()
{
NSBundle.MainBundle.LoadNib("MyCustomCell", this, null);
}
Если вы этого не сделаете, и ваша реализация отличается, но вы все еще используете LoadNib в конструкторе, выходы по-прежнему не удастся сохранить. Они созданы хорошо, но они не сохранены. Это не MonoTouch GC, который запускает или что-то еще, это нативная розетка, которая выпускается автоматически. Вы можете спросить: «Но почему я могу использовать LoadNib в конструкторе UIViewController и все еще получать мои розетки?». Это правильно, вы можете использовать LoadNib в конструкторе UIViewController, но есть одно важное отличие: этот 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:
Можете ли вы NIB это?
Руководство по программированию ресурсов Apple для файлов NIB
Надеюсь, это поможет.