#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, меняющий логику модальные контроллеры, и просто слишком долго играл с этим материалом, думая, что это было причиной. Я не знаю, почему мне потребовалось так много времени, чтобы погуглить сообщение об исключении… но теперь все это имеет полный смысл!