-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ios/catalyst] fix memory leak in ToolbarItem
#22893
Conversation
Fixes: dotnet#22814 `ToolbarItem` has a circular reference that causes it to live forever: * `ToolbarItem` -> `ToolbarItemExtensions.PrimaryToolbarItem` -> `ToolbarItem` And then if you have a `Page` such as: class LeakyShellPage : ContentPage { public LeakyShellPage() { var item = new ToolbarItem { Text = "Primary Item" }; item.Clicked += OnToolbarItemClicked; ToolbarItems.Add(item); } // Needs to be an instance method void OnToolbarItemClicked(object sender, EventArgs e) { } } Then the `ToolbarItem` (that leaks), would also cause the entire `Page` to leak as it has a strong reference to it. I could reproduce this problem by updating a tests in `ShellTests.cs` to add a `ToolbarItem`. To solve this problem, I changed the `_item` field in both `PrimaryToolbarItem` and `SecondaryToolbarItem` to be a `WeakReference`. While writing tests, I found there was a mismatched `#if` and `#endif`. I think part of `ShellTests.cs` were not running at all on `MACCATALYST` by accident. So, I hope they still pass?
@@ -82,6 +82,7 @@ public async Task PageLayoutDoesNotExceedWindowBounds() | |||
Assert.True(pageBounds.Height <= window.Height); | |||
}); | |||
} | |||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this accidentally put #if !MACCATALYST
across this entire file. 👀 Might have been a merge conflict?
|
||
Clicked += (sender, e) => ((IMenuItemController)_item).Activate(); | ||
Clicked += OnClicked; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't change this to:
Clicked += OnClicked; | |
Clicked += (sender, e) => ((IMenuItemController)item).Activate();; |
This created a closure on item
that also leaked.
Fixes: #22814
ToolbarItem
has a circular reference that causes it to live forever:ToolbarItem
->ToolbarItemExtensions.PrimaryToolbarItem
->ToolbarItem
And then if you have a
Page
such as:Then the
ToolbarItem
(that leaks), would also cause the entirePage
to leak as it has a strong reference to it. I could reproduce this problem by updating a tests inShellTests.cs
to add aToolbarItem
.To solve this problem, I changed the
_item
field in bothPrimaryToolbarItem
andSecondaryToolbarItem
to be aWeakReference
.While writing tests, I found there was a mismatched
#if
and#endif
.I think part of
ShellTests.cs
were not running at all onMACCATALYST
by accident. So, I hope they still pass?