Исключение MonoTouch: Селектор, вызванный из объекта-c, управляемого объекта типа, который был GC'ed

Я получаю это исключение в своем приложении MonoTouch, и я не могу его исправить. Я пробовал около 6 часов, и мне не повезло.

Мое понимание этого исключения заключается в том, что объект ссылается (или пытается ссылаться) на MonoTouch, но Garbage Collection уже удалил его. Поэтому он пытается снова создать ссылку на него, используя конструктор, который я не задал в классе, используя указатель.

Первоначально я думал, что добавления этого конструктора будет достаточно, пока я не сделаю некоторые исследования, и понял, что в лучшем случае это будет временная повязка. То, что я нахожу странным, заключается в том, что, насколько я вижу, я держу ссылку на все. Я даже немного переборщил и начал создавать переменные-члены для вещей, которые необязательно нужно хранить, чтобы попытаться захватить исключение, но все равно ничего.

Ошибка возникает, когда я загружаю ViewController, запускаю делегат, который нажимает новый ViewController на NavigationController (оставляя экран), нажав кнопку «Назад» и снова переходя на другое представление. Это последовательно происходит одинаково и всегда будет терпеть крах в этот момент, хотя и не обязательно в то же самое время из-за того, как работает GC.

Приложение довольно просто. Первый экран загружает 5 различных диаграмм, используя ShinobiCharts. Источники данных и делегаты установлены в ViewController, и ViewModel отправляется в представление, которое затем добавляет диаграммы в subview. Исключение происходит в ColumnChart (пользовательский класс, наследуемый от ShinobiChart). Исключение всегда будет выбрано для этих элементов управления, никогда не будет View или ViewController. Однако, какая диаграмма заставляет исключение кажутся случайными каждый раз.

Как я храню диаграммы выглядит следующим образом:

public class HomeViewModel { public ColumnChart MeetingsChart { get; set; } public ColumnChart FirmDataChart { get; set; } public ColumnChart SystemUseChart { get; set; } public BarChart IllustrationsChart { get; set; } public PieChart TermsOfBusinessChart { get; set; } public ColumnChartDataSource MeetingsChartDataSource { get; set; } public ColumnChartDataSource SystemUseChartDataSource { get; set; } public StackChartDataSource FirmDataChartDataSource { get; set; } public BarChartDataSource IllustrationsChartDataSource { get; set; } public PieChartDataSource TermsOfBusinessDataSource { get; set; } public BarChartDataProvider TermsOfBusinessDataProvider { get; set; } public DashboardMeetingChartDelegate MeetingsChartDelegate { get; set; } public ColumnChartDelegate SystemUseChartDelegate { get; set; } public PieChartDelegate TermsOfBusinessDelegate { get; set; } } 

Этот класс затем реализуется в контроллере следующим образом: (ПРИМЕЧАНИЕ. Многие коды были удалены, поскольку я не думал, что это необходимо)

 public class HomeController : UIViewController { private HomeView _homeView; private HomeViewModel _homeViewModel; ….. public HomeController() { _homeViewModel = new HomeViewModel(); } …. private void LoadCharts() { _homeViewModel.MeetingsChart = LoadMeetingsChart(); _homeViewModel.FirmDataChart = LoadFirmDataChart(); _homeViewModel.SystemUseChart = LoadSystemUseChart(); _homeViewModel.IllustrationsChart = LoadIllustrationsChart(); _homeViewModel.TermsOfBusinessChart = LoadTermsOfBusinessChart(); } private ColumnChart LoadMeetingsChart() { ColumnChart meetingsChart = new ColumnChart(RectangleF.Empty); meetingsChart.DataSource = _homeViewModel.MeetingsChartDataSource; meetingsChart.Delegate = _homeViewModel.MeetingsChartDelegate; meetingsChart.LicenseKey = LICENSE_KEY; return meetingsChart; } } 

Наконец, вид:

 public class HomeView : UIView { private HomeViewModel _homeViewModel; public HomeView(RectangleF frame, UINavigationController navigationController, HomeViewModel homeViewModel) : base(frame) { this._homeViewModel = homeViewModel; this.BackgroundColor = UIColor.FromRGB(20, 20, 20); this.Title = "Sales 360 Dashboard"; SetupChartBounds(UIApplication.SharedApplication.StatusBarOrientation); } public void SetupCharts() { SetupMeetingsChartHeaderBar(); SetupTermsOfBusinessChartHeaderBar(); SetupIllustrationsChartHeaderBar(); SetupSystemUserChartHeaderBar(); SetupFirmDataChartHeaderBar(); this.AddSubview(_homeViewModel.MeetingsChart); this.AddSubview(_homeViewModel.TermsOfBusinessChart); this.AddSubview(_homeViewModel.IllustrationsChart); this.AddSubview(_homeViewModel.SystemUseChart); this.AddSubview(_homeViewModel.FirmDataChart); } } 

Я бы очень признателен за любую помощь по этой проблеме, поскольку я сильно застрял на ней. Благодарю.

ИЗМЕНИТЬ 1:

HomeController вытолкнут из того, что называется SplashController. Единственная цель SplashController – отобразить представление заставки и вызвать веб-службы. Веб-службы называются асинхронно, и по завершении изменит представление на домашний вид, где отображаются все диаграммы.

Вот некоторые из классов SplashController:

 public class SplashController : UIViewController { private SplashView _splashView; private SplashViewModel _splashViewModel; private readonly string BACKGROUND_IMAGE_PATH; private HomeController _homeController; ..... public override void LoadView() { LoadViewModel(); _splashView = new SplashView(new RectangleF(0, 0, Dimensions.Width, Dimensions.Height), _splashViewModel); this.View = _splashView; } // .... a number of service calls eventually leading to this protected void GetTermsOfBusinessAllAgentsCompleted(object sender, GetTermsOfBusinessAllAgentsCompletedEventArgs e) { _servicesHelper.StopTimer(e.UserState as Timer); if (e.Error != null) HandleError(e.Error, "Terms of Business"); else { _termsOfBusinessGraphData = e.Result; ChangeViewToHomeView(); } } private void ChangeViewToHomeView() { _homeController = new HomeController(_meetingsGraphData, _firmDataGraphData, _systemUseGraphData, _illustrationsGraphData, _termsOfBusinessGraphData); this.NavigationController.PushViewController(_homeController, false); } } 

HomeView создается в методе LoadView, переопределенном в классе HomeController, и в основном выглядит следующим образом:

 _homeView = new HomeView(new RectangleF(0, 0, Dimensions.Width, Dimensions.Height), this.NavigationController, _homeViewModel); this.View = _homeView; 

Что касается NavigationController, хороший вопрос. Это было то, что я делал раньше, когда я передавал NavigationController делегату. Однако теперь все это делается в HomeController, поэтому он больше не нужен. Извини за это, моя ошибка! Я сейчас понял это и попробовал перезапустить приложение, так же все еще происходит. Пожалуйста, проигнорируйте этот бит.

EDIT 2:

Вот делегат для одной из диаграмм. Я пропустил методы, которые обрабатывают ошибки, поскольку они не нужны. Метод _meetingServices.GetAgentsData вызывает в этом методе веб-службу, которая затем возвращается к событию в этом объекте:

 public class DashboardMeetingChartDelegate : SChartDelegate { private UINavigationController _navigationController; private CategoryGraph _meetingsGraphData; private MeetingServices _meetingServices; private ServicesHelper _servicesHelper; private int _currentIndex; public DashboardMeetingChartDelegate(UINavigationController navigationController, CategoryGraph meetingsGraphData) { this._navigationController = navigationController; this._meetingsGraphData = meetingsGraphData; _meetingServices = new MeetingServices(); _servicesHelper = new ServicesHelper(); _currentIndex = -1; } protected override void OnToggledSelection (ShinobiChart chart, SChartDataPoint dataPoint, SChartSeries series, PointF pixelPoint) { _currentIndex = dataPoint.Index; _meetingServices.GetAgentsData(GetAgentsCompleted); } protected void GetAgentsCompleted(object sender, GetAgentsCompletedEventArgs e) { _servicesHelper.StopTimer(e.UserState as Timer); if (e.Error != null) HandleError(e.Error); else { int rsmId = Convert.ToInt32(_meetingsGraphData.Data[0].SeriesDataPoints[_currentIndex].PointMetaData); AgentContract currentAgent = e.Result.Agents.Where(agent => agent.Id == rsmId).First(); _navigationController.PushViewController(new MeetingController(currentAgent), true); } } 

И вот MeetingController – довольно похожий на другой, за исключением того, что нагрузка меньше:

 public class MeetingController : UIViewController { private AgentContract _currentAgent; private RsmChartView _meetingView; private RsmChartViewModel _meetingViewModel; private MeetingTypeController _meetingTypeController; private ColumnChartDataProvider _columnChartDataProvider; public MeetingController(AgentContract currentAgent) { _currentAgent = currentAgent; } public override void LoadView () { LoadColumnChartDataProvider(); LoadViewModel(); InitialiseView(); } private void LoadColumnChartDataProvider() { _columnChartDataProvider = new ColumnChartDataProvider(); _columnChartDataProvider.XValueList.Add(new NSString("Phone")); _columnChartDataProvider.XValueList.Add(new NSString("Demo")); _columnChartDataProvider.XValueList.Add(new NSString("Fact Finding")); _columnChartDataProvider.YValueList.Add(61); _columnChartDataProvider.YValueList.Add(22); _columnChartDataProvider.YValueList.Add(27); } private void LoadViewModel() { _meetingViewModel = new RsmChartViewModel(); _meetingViewModel.Chart = LoadMeetingChart(); _meetingViewModel.RsmContentModel = LoadRsmContentModel(); } private RsmContentModel LoadRsmContentModel() { RsmContentModel model = new RsmContentModel(); model.Name = _currentAgent.Name; return model; } private void InitialiseView() { _meetingView = new RsmChartView(new RectangleF(0, 0, Dimensions.Width, Dimensions.Height), _meetingViewModel); this.View = _meetingView; } private ColumnChart LoadMeetingChart() { ColumnChart meetingChart = new ColumnChart(new RectangleF(10, 220, Dimensions.Width - 20, 540)); _meetingTypeController = new MeetingTypeController(); _meetingViewModel.ChartDataSource = new ColumnChartDataSource(_columnChartDataProvider); _meetingViewModel.ChartDelegate = new ColumnChartDelegate(this.NavigationController, _meetingTypeController); meetingChart.DataSource = _meetingViewModel.ChartDataSource; meetingChart.Delegate = _meetingViewModel.ChartDelegate; return meetingChart; } public override void ViewDidLoad() { _meetingView.Load(); } } 

Это условие часто трудно отлаживать. Некоторые изменения были внесены в MonoTouch для уменьшения таких случаев.

Чтобы попробовать их, я предлагаю вам попробовать 6.0.7 (на бета-канале) и сообщить о какой-либо неполадке в списке рассылки (или в отчете об ошибке).

Более подробную информацию можно найти в примечаниях к выпуску ( прямая ссылка ).

  • Xamarin DesignTime Custom Controls Render в XCode, редактировать свойства управления в DesignTime
  • Интегрируйте Admob в приложение iOS, которое использует monogame
  • Не удается найти класс Foundation.NSJavaScriptExtension в расширении приложения
  • xamarin.iOS Вертикальная прокрутка изображений
  • Использование навигации SlideOut в приложении MonoCross iOS
  • Стиль DateElement в Monotouch.Dialog
  • Должен ли я держать соединение Sqlite открытым?
  • Xamarin Forms ios, отображающий «default» вместо значка Hamburger
  • MakeGenericMethod / MakeGenericType на Xamarin.iOS
  • Как создать такой макет в xamarin?
  • UINavigationController прокручивается по кнопке «Назад»
  • Interesting Posts

    iPhone UINavigationBar – настройка ширины и поля rightBarButtonItem

    Множественная выборка для мобильного Safari

    Добавить UIProgressView под навигационным контроллером

    Программный набор делегата для UICollectionView не работает

    NSUserDefaults синхронизируется с iCloud? Я не хочу, чтобы они были

    поместите CLLocationCoordinate2D в CLLocation для Swift

    Звуковой сигнал уведомления IOS VOIP отменяет отмену DND и звонка

    Ссылка на iOS для магазина приложений перед отправкой приложения

    Жест iOS не обнаружен из-за настроек доступности

    Остановить UIImageView от возврата в исходное местоположение в представлении?

    Проинформирование контроллера просмотра программно с помощью раскадровки из AppDelegate

    Когда сторона сбоку добавляет новый элемент в это время, как загрузить табличный вид?

    UICollectionView удаляет пробел / заголовок iOS11

    Символ веб-шрифта «обменивается» на OSX и iOS на определенном веб-сайте

    3d Touch недоступен на iPhone 6s +

    Давайте будем гением компьютера.