Должен ли я реализовать конструктор IntPtr UIViewController? - PullRequest
1 голос
/ 05 декабря 2011

Это как-то связано с другим вопросом, который я написал: Какие есть варианты для поиска исключений Monotouch, таких как «System.Exception: селектор, вызываемый из target-c для управляемого объекта, который был GC'ed»? .

Я получаю отчеты о сбоях от своих тестеров, и почти для всех моих контроллеров UIViewController я получаю сообщения об ошибках:

System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed ---> System.MissingMethodException: No constructor found for Browser.FolderListController::.ctor(System.IntPtr)

Я не знаю, что я делаю что-то явно неправильно, и я не могу отследить проблемы, но я знаю, что ни в одном из случаев я не переопределяю конструктор IntPtr . Вопрос в том, должен ли я это реализовать? Это заставит проблемы уйти? Каковы будут последствия, если ObjC возродит контроллер GC с помощью этого конструктора?

EDIT:

Я нашел, по крайней мере, одну причину проблем, следуя советам Рольфа и Пупуса, и установил поток, который собирал 10 раз в секунду, чтобы я мог вызвать сбой. Я активно использую NSNotificationCenter . Я регистрирую своих наблюдателей в ViewDidLoad() и отменяю регистрацию в ViewDidUnload(). Однако код, который выполняется, если приходит уведомление manipulates the controller's view. Это означает, что есть вероятность, что обработчик сработает ПОСЛЕ ViewDidDisappear(). И если представление уже получено с помощью GC, оно будет аварийно завершено. Я исправил это, переместив свою подписку в NSNOtificatioCenter в ViewWillAppear() и ViewWillDisappear().

Ответы [ 2 ]

3 голосов
/ 05 декабря 2011

Нет, вы не должны переопределять конструктор IntPtr.

Вы будете только скрывать проблемы в своем коде, а не решать их.

Некоторые (но не все) последствия возрождения контроллера GC: * ​​1005 *

  • Все управляемое состояние исчезнет. Любые (управляемые) переменные, которые были у вас в исходном контроллере, вернутся в исходное состояние (поскольку теперь у вас есть новый управляемый экземпляр контроллера).
  • GC мог освободить любые другие объекты, на которые ссылался ваш контроллер (это может включать такие вещи, как делегаты, которые вы не можете так легко воссоздать. Если управляемый делегат освобождается и затем вызывается, вы в конечном итоге с довольно трудно отследить родной сбой).
  • Все, что зависит от синхронизируемых управляемых и собственных объектов, будет иметь неопределенное поведение (это может включать код внутри MonoTouch, который вы не контролируете).

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

Если вы хотите временное решение, создайте статический список и поместите все экземпляры вашего контроллера в этот список. Это потребует некоторого количества памяти (в зависимости от того, сколько объектов вы создаете), но вам не придется иметь дело с неопределенным и неподдерживаемым поведением.

0 голосов
/ 16 декабря 2011

Просто возникла та же проблема, когда я загружал новый DetailViewController из моего основного RootViewController с помощью IB Storyboard. В Storyboard уже было создано событие перехода push, созданное для нового детального просмотра всех в Storyboard. Однако мне нужно было динамически выдвигать другое представление в зависимости от содержимого ячейки. В любом случае, как только я убрал переходную передачу в DetailView из раскадровки и программно попытался выдвинуть новый контроллер представления, именно тогда я получил ошибку GC.

В итоге я поцарапал раскадровку и просто использовал простые xib-файлы и смог сделать то же самое. Теперь я с подозрением отношусь к тому, что GC работает с раскадровкой.

Инструменты: Xcode 4.2.1 и MonoDevelop 2.8.5

...