Не найден конструктор для ViewController ::.ctor (System.IntPtr)

#xamarin.ios

#xamarin.ios

Вопрос:

У меня возникла проблема, из-за которой мое приложение Monotouch иногда выходит из строя сразу после получения предупреждения о памяти. Пожалуйста, посмотрите эту трассировку стека ниже.

Получено предупреждение о памяти. Уровень = 2
DTMobileIS[2299] : _memoryNotification : {
 OSMemoryNotificationLevel = 2; 
 временная метка = "2011-04-11 14:29:09  0000";
 }
Исключение верхнего уровня: System.missingmethod Исключение: Не найден конструктор для Myapp.UI.BoardController::.ctor (System.IntPtr)
 в системе.Активатор.CreateInstance (System.Введите type, BindingFlags bindingAttr, System.Отражение.Связующий binder, System.Object[] аргументы, System.Глобализация.CultureInfo культура, система.Объект [] activationAttributes) [0x00000] в :0 
 в системе.Активатор.CreateInstance (System.Введите type, System.Object[] аргументы, System.Объект [] activationAttributes) [0x00000] в :0 
 в системе.Активатор.CreateInstance (System.Введите type, System.Объект [] аргументы) [0x00000] в : 0 
 в MonoTouch.ObjCRuntime.Время выполнения.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] в : 0 
 в MonoTouch.ObjCRuntime.Время выполнения.GetNSObject (IntPtr ptr) [0x00000] в : 0 
 в MonoTouch.ObjCRuntime.Время выполнения.GetNSObjectWrapped (IntPtr ptr) [0x00000] в : 0 
 в (оболочке, встроенной в управляемый) MonoTouch.ObjCRuntime.Среда выполнения: GetNSObjectWrapped (intptr)
 в MonoTouch.UIKit.Пользовательское приложение.Main (System.Строка[] аргументов, System.Строка principalClassName, System.Строка delegateClassName) [0x00000] в :0 
 в Myapp.Free.Приложение.Main (System.Строка [] аргументов) [0x00000] в /Users/haakon/Code/Myapp-work/iOS/Myapp.Free/Myapp.Free/Main.cs:12 

Трассировка стека верна в том смысле, что в указанном классе (BoardController, который является подклассом UIViewController) отсутствует конструктор, принимающий параметр IntPtr. Но это сделано намеренно, поскольку я вообще не использую Interface Builder в своем приложении. Итак, почему это происходит?

Я нашел похожий вопрос, который, казалось, предполагал, что это может произойти, если вы позволите вашим представлениям (или, возможно, контроллерам просмотра) собирать мусор. Но я не понимаю, как это может произойти здесь. Немного предыстории: Мой делегат приложения содержит строгую ссылку на контроллер навигации, который, в свою очередь, содержит строгую ссылку на корневой контроллер представления в стеке навигации. Этот корневой контроллер представления также содержит строгую ссылку на экземпляр BoardController. Итак, я не понимаю, как возможно, что BoardController собирает мусор.

Есть идеи?

Ответ №1:

Конструктор IntPtr используется, когда собственный объект должен быть преобразован в управляемый объект. В этом конкретном случае вы могли бы создавать, например, это:

  var foo = new Foo ();
 SomeObject.Property = foo;
  

Это присваивает объекту Foo свойство, но если свойство является объектом Objective-C, если вы не сохраните ссылку на «foo», то GC Mono продолжит работу и удалит связь между управляемым Foo и неуправляемым Foo .

Затем, позже, вы пытаетесь его извлечь:

  var bar = SomeObject.Property;
  

Здесь MonoTouch узнает, что управляемого объекта больше нет, кроме отображений на него, поэтому он должен создать новый, но все, что у него есть, это IntPtr для кода Objective-C. Вот почему вам нужен конструктор.

У вас может возникнуть соблазн просто добавить собственный конструктор, и это нормально во многих случаях, но это проблема, если ваш объект имеет собственное состояние, хранящееся в управляемом мире, например:

  public class Foo : UIView {
     string Name;
     public Foo () { Name= "Hello"; }
     public Foo (IntPtr ptr) : base (ptr) {}
 }
  

В этом случае конструктор IntPtr не может полностью восстановить управляемый объект и его состояние только из IntPtr. Итак, вероятный источник вашей проблемы заключается в том, что вы не сохраняете ссылку на свой объект.

Итак, реальное исправление вкратце таково: сохраните ссылку на ваш BoardController в вашем управляемом коде, чтобы предотвратить сбор объекта, когда вы все еще собираетесь использовать его позже.

Комментарии:

1. СПАСИБО. ВЫ. МИГЕЛЬ!!!! Я боролся с этим целую вечность. Я получил какой-то странный контроллер корневого представления nav / tab / single / dialog, меняющий логику модальные контроллеры, и просто слишком долго играл с этим материалом, думая, что это было причиной. Я не знаю, почему мне потребовалось так много времени, чтобы погуглить сообщение об исключении… но теперь все это имеет полный смысл!