Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class PhoneFlyoutPageRenderer : UIViewController, IPlatformViewHandler
{
UIView _clickOffView;
UIViewController _detailController;
VisualElement _element;
WeakReference<VisualElement> _element;
bool _disposed;

UIViewController _flyoutController;
Expand Down Expand Up @@ -75,7 +75,7 @@ bool Presented
get { return _presented; }
}

public VisualElement Element => _viewHandlerWrapper.Element ?? _element;
public VisualElement Element => _viewHandlerWrapper.Element ?? _element?.GetTargetOrDefault();

public event EventHandler<VisualElementChangedEventArgs> ElementChanged;

Expand All @@ -100,7 +100,7 @@ public void SetElement(VisualElement element)
_clickOffView = new UIView();
_clickOffView.BackgroundColor = new Color(0, 0, 0, 0).ToPlatform();
_viewHandlerWrapper.SetVirtualView(element, OnElementChanged, false);
_element = element;
_element = new(element);

if (_intialLayoutFinished)
{
Expand Down Expand Up @@ -269,9 +269,7 @@ protected override void Dispose(bool disposing)
}

EmptyContainers();

Page.SendDisappearing();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't be here. We are already calling this above

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it matter if we just leave it?

Copy link
Contributor Author

@bhavanesh2001 bhavanesh2001 Apr 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PureWeen Without the PR changes, since we’re inside Dispose, the wrapper’s Element will be null at this point — so Page falls back to the strongly referenced _element:

public VisualElement Element => _viewHandlerWrapper.Element ?? _element;

With the PR changes, _element is resolved through a weak reference, so keeping the SendDisappearing() call here won’t make a difference

Let me know if you think I should keep the call.


_element = null;
_disposed = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,39 @@ await CreateHandlerAndAddToWindow<FlyoutViewHandler>(flyoutPage, async (handler)
});
}

[Fact(DisplayName = "FlyoutPage as Modal Does Not Leak")]
public async Task DoesNotLeakAsModal()
{
SetupBuilder();

var references = new List<WeakReference>();
var launcherPage = new ContentPage();
var window = new Window(launcherPage);

await CreateHandlerAndAddToWindow<WindowHandlerStub>(window, async handler =>
{
var flyoutPage = new FlyoutPage
{
Flyout = new ContentPage
{
Title = "Flyout",
IconImageSource = "icon.png"
},
Detail = new ContentPage { Title = "Detail" }
};

await launcherPage.Navigation.PushModalAsync(flyoutPage, true);

references.Add(new WeakReference(flyoutPage));
references.Add(new WeakReference(flyoutPage.Flyout));
references.Add(new WeakReference(flyoutPage.Detail));

await launcherPage.Navigation.PopModalAsync();
});

await AssertionExtensions.WaitForGC(references.ToArray());
}

bool CanDeviceDoSplitMode(FlyoutPage page)
{
return ((IFlyoutPageController)page).ShouldShowSplitMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public MainPage()
{
VerticalOptions = LayoutOptions.Center,
HorizontalTextAlignment = TextAlignment.Center,
Text = "Page 1"
Text = "Page 1",
AutomationId = "MauiLabel"
});

Content = stack;
Expand Down Expand Up @@ -48,8 +49,7 @@ async void StartTrackPage2()
{
while (true)
{
((Label)((StackLayout)Content).Children[0]).Text =
string.Format("Page1. But Page2 IsAlive = {0}", _page2Tracker.IsAlive);
((Label)((StackLayout)Content).Children[0]).Text = _page2Tracker.IsAlive ? "Failed" : "Success";
await Task.Delay(1000);
GarbageCollectionHelper.Collect();
}
Expand All @@ -60,12 +60,12 @@ public class Page2 : FlyoutPage
{
public Page2()
{
Flyout = new Page()
Flyout = new ContentPage
{
Title = "Flyout",
IconImageSource = "Icon.png"
};
Detail = new Page() { Title = "Detail" };
Detail = new ContentPage() { Title = "Detail" };
}

protected override async void OnAppearing()
Expand All @@ -75,6 +75,10 @@ protected override async void OnAppearing()
await Task.Delay(1000);
await Navigation.PopModalAsync();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#if IOS
using NUnit.Framework;
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

Expand All @@ -14,15 +13,12 @@ public Bugzilla31255(TestDevice testDevice) : base(testDevice)
public override string Issue => "Flyout's page Icon cause memory leak after FlyoutPage is popped out by holding on page";

[Test]
[Ignore("The sample is crashing. More information: https://github.com/dotnet/maui/issues/21206")]
[Category(UITestCategories.Navigation)]
[Category(UITestCategories.Compatibility)]
public async Task Bugzilla31255Test()
public void Bugzilla31255Test()
{
App.Screenshot("I am at Bugzilla 31255");
await Task.Delay(5000);
App.WaitForNoElement("Page1. But Page2 IsAlive = False");
App.AssertMemoryTest();
}
}
}
#endif
}
Loading