RemoveFromNavigation Keeps Page and PageModel Alive
If you remove a page from the navigation stack by calling:
CoreMethods.RemoveFromNavigation<PageModelHere>();
The PageModel is kept alive because the next PageModel in the stack still holds a reference to it in PreviousPageModel. The Page is also kept alive because the PageModel has a reference to it.
This isn't a problem if you are removing the previous Page from the navigation, as in: Page A > Page B inside Page B's PageModel you would do:
CoreMethods.RemoveFromNavigation<ExtendedSplashPageModel>(true);
PreviousPageModel = null;
Now Page A and Page A's PageModel are cleared from memory.
In my case I was just removing the previous page from the navigation stack, so it was simple to fix my little leak. If you have a complex navigation stack, I imagine it can get a little tricky to find the right PageModel to remove the PreviousPageModel from.
Are you sure with that? did you profile it? i have this usage also very often and i am seeing that pages are removed without from the stack(not sure about memory). because when I click back button i am not page A. i never needed PreviousPageModel = null; How did you come to that conclusion?
if your theory is correct, it will be enough to extend
/// <summary>
/// Remove specific page/pagemodel from navigation
/// </summary>
public void RemoveFromNavigation<TPageModel> (bool removeAll = false) where TPageModel : FreshBasePageModel
{
//var pages = this._currentPage.Navigation.Where (o => o is TPageModel);
foreach (var page in this._currentPage.Navigation.NavigationStack.Reverse().ToList())
{
if (page.BindingContext is TPageModel)
{
page.GetModel()?.RaisePageWasPopped ();
this._currentPage.Navigation.RemovePage (page);
if (_currentPageModel.PreviousPageModel is TPageModel)
_currentPageModel.PreviousPageModel = null;
if (!removeAll)
break;
}
}
}
But how should we handle in case we have navigation like below
A->B->C->D
you want to remove B and C when you are on D. I guess if you remove C successfully without having any reference on D. B should be also removed.
CoreMethods.RemoveFromNavigation<CPageModel>(true);
CoreMethods.RemoveFromNavigation<BPageModel>(true);
Depends how you want to do it. If you have A->B->C->D and you remove B and C, you could update Ds PreviousPageModel to A or just null it. In my app it starts and I show an ExtendedSplashPage on Android and UWP. The ExtendedSplashPage just does some loading and initializing then pushes the Home Page. I only do it this way because when setting MainPage in Xamarin Forms it causes a brief flicker. So I just set the MainPage to my NavigationContainer and then remove the ExtendedSplashPage because its only needed briefly in the beginning and then never again.