0

いくつかの MvvmCross ビデオ ( http://www.youtube.com/watch?v=cYu_9rcAJU4&feature=youtu.be&t=33m41s )で以前に説明したように

ビューモデルからビューへの強い参照を削除しようとしています。

PropertyChanged += が使用されている WeakSubscribe() を実装したので、アクションを使用してビューを観察できるようにするいくつかのシナリオに出くわしました。これにより、メモリリークが再び発生する可能性があると思われるため、根絶を試みます。

ただし、WeakReference は INotifyPropertyChanged ソースへのフックに基づいて機能します。

https://github.com/MvvmCross/MvvmCross/blob/162a816d148df224df0b8f635aeafe30c0910de9/CrossCore/Cirrious.CrossCore/WeakSubscription/MvxWeakSubscriptionExtensionMethods.cs

では、弱い参照を介してビューに通知できるように、コードをリファクタリングして Action を破棄し、PropertyChanged を介して起動する必要がありますか?

以下は、現在の強く参照されているアーキテクチャのサンプル コードです。

ビューモデル

    public event Action Loaded;
    public HomeViewModel()
    {
        FeaturedProductCategoryViewModel = new FeaturedProductsViewModel();
        FeaturedProductCategoryViewModel.OnPopulated += () =>
        {
            if (Loaded != null) Loaded();
        };
    }

意見

    public MainHomePageView()
        : base(GetNibName("MainHomePageView"), null)
    {
        this.EnableLandscapeRotation ();
    }

    protected override void ViewJustLoaded()
    {
        this.ViewModel.Loaded += LoadControls;
    }

    void LoadControls()
    {
        //load controls when view model is populated
    }
4

2 に答える 2

1

MvvmCross の弱参照アプローチの背後にある考え方は、ViewModel が View への参照を持つべきではないということです。

これの背景はhttps://stackoverflow.com/a/14734264/373321にあります

Loadedみたいなちょっと変わったタイプのイベントの場合は、新しい拡張メソッドとハンドラActionを使ってサブスクライブできると思います。WeakSubscribe

Loadedまたは、EventHandler型に変更してからWeakSubscribe(this EventInfo eventInfo, ...拡張メソッドを使用することもできます。

  // ViewModel - define event
  public event EventHandler Loaded;

  // View - subscription
  IDisposable _subscription;

  // View - in ViewDidLoad
  _subscription = typeof(HomeViewModel)
                      .GetEvent("Loaded")
                      .WeakSubscribe(this.ViewModel, OnLoaded);

  // View - event handler
  public void OnLoaded(object sender, EventArgs e)
  {
     LoadControls();
  }
于 2013-10-15T11:17:47.267 に答える
0

より良い解決策は、ビュー モデルに bool プロパティ (IsBusy と呼ばれる) を設定し、読み込みを開始するときに IsBusy を true に設定することだと思います。読み込みが完了したら、false に戻します。次に、ビューで mvvmcross プロパティ リスナーを使用して、読み込みの終了を処理します

        listener = new MvxPropertyChangedListener(IncidentViewModel).Listen<bool>(
            () => IncidentViewModel.IsBusy,
            () =>
            {
                if (IncidentViewModel != null && !IncidentViewModel.IsBusy)
                {
                    LoadControls();
                }
            });
于 2015-10-20T10:47:30.273 に答える