2013-10-15 26 views
0

正如前面所詳述的一些MvvmCross視頻(http://www.youtube.com/watch?v=cYu_9rcAJU4&feature=youtu.be&t=33m41s弱引用與行動<T>

我想刪除我的意見從我的視圖模型強引用。

已實施WeakSubscribe(),其中的PropertyChanged + =已使用我現在所遇到的一些情形,我用行動來讓視圖來觀察。我認爲這會導致再次潛在的內存泄漏,因此試圖erradicate。

但是 - WeakReference的工作掛鉤到INotifyPropertyChanged的源的基礎上:

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

所以我應該重構我的代碼溝的行動,並要通過的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 
    } 

回答

0

背後MvvmCross'弱引用方法的駕駛心態是的ViewModels應該永遠不會有意見的引用 - 因爲如果他們這樣做,然後它可以導致視圖引用其包含的視圖。

一些背景是在https://stackoverflow.com/a/14734264/373321

在像Loaded事件的情況下,與它的有點不正規Action類型,我認爲這是可以訂閱使用新WeakSubscribe擴展方法和處理程序。

或者你可以改變LoadedEventHandler類型,然後使用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(); 
    } 
+0

你寫「的ViewModels應該永遠不會有意見的參考」。但事實已經如此。那麼,爲什麼你會使用WeakSomething? – Softlion

0

我想一個更好的解決辦法是在視圖模型一個布爾屬性(叫IsBusy)然後,當你開始加載 - 設置IsBusy爲true。當您完成加載時 - 將其設置爲false;那麼在您看來,使用mvvmcross屬性監聽器作用於負載整理

 listener = new MvxPropertyChangedListener(IncidentViewModel).Listen<bool>(
      () => IncidentViewModel.IsBusy, 
      () => 
      { 
       if (IncidentViewModel != null && !IncidentViewModel.IsBusy) 
       { 
        LoadControls(); 
       } 
      });