MvvmCross (Android), кажется, держится за ViewModels и никогда не избавляется, чего мне не хватает - PullRequest
0 голосов
/ 04 января 2019

Если вы используете MvvmCross, у вас есть очень простая модель представления, которая подписывается на сообщение через MvxMessager, даже когда представление, в котором оно включено, модель представления остается в памяти и все еще получает эти сообщения. Мне удалось воспроизвести его в очень простом приложении, поместив несколько получателей на Действия / Фрагменты, которые впоследствии будут уничтожены, но когда сообщение отправляется с помощью другого действия, модели представлений все еще остаются живыми? Если одна и та же модель представления перемещалась и затем закрывалась несколько раз, сообщение принимается каждым экземпляром созданной модели представления.

Я должен отметить, что это слабые ссылки, которые я использую для MvxMessenger, и в моих моделях представлений нет статических ссылок, и я явно избавляюсь от своих действий через Dispose.

Похоже, что это проблема и для всех образцов MvvmCross (TipCalc / Star Wars).

Я мог бы просто отписаться вручную, но я бы надеялся, что токен Weak Reference от MvxMessenger этого не сделает.

Стивен

1 Ответ

0 голосов
/ 10 января 2019

Поскольку используемый вами вид располагается не обязательно, это означает, что связанный ViewModel удаляется. Xamarin использует несколько способов для сбора мусора. Вы можете прочитать больше о сборке мусора в приложениях Xamarin здесь . Например, в Sgen сборка мусора происходит, когда в определенной куче заканчивается свободное место. Имея это в виду, что если ваше приложение не использует много памяти, может потребоваться значительное количество времени, пока ваши модели представления не будут эффективно утилизированы.

Существует несколько рекомендаций, которые можно использовать для предотвращения этого:

  • Для ViewModels утилизируйте свои подписки, когда ViewModel больше не отображается на экране. Чаще всего никогда не требуется обновлять пользовательский интерфейс, пока экран не виден на экране. Я обычно подписываюсь на события в ViewAppearing и отписываюсь в ViewDisappearing.
  • [необязательно] Определите, могут ли одновременно существовать несколько экземпляров определенной модели представления. Например, можете ли вы когда-либо иметь несколько экземпляров LoginViewModel одновременно? В этом случае вы можете реализовать логику, гарантирующую, что только один экземпляр ViewModel может иметь подписку на данное сообщение и purge старую подписку. Вы можете удалить старые подписки для типа сообщения, используя:

    MvxMessengerHub.RequestPurge (TypeOf (TStoreMessage));

Лучший способ понять, как работает MvxMessengerHub , или MvvmCross в целом, это прочитать его исходный код.

...