Skip to content
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

Formalize virtual layout concepts and fix iOS memory leaks #15303

Merged
merged 10 commits into from
Jun 22, 2023

Conversation

hartez
Copy link
Contributor

@hartez hartez commented May 26, 2023

Description of Change

Proposed alternative to #15193

Formalizes the concept of the layout backing controls having CrossPlatformMeasure and CrossPlatformArrange methods which they call during the layout process; also allows the handlers to make modifications as necessary to those methods (e.g., normalizing the ScrollView behavior across all the platforms).

This includes the GC tests from #15193 and makes the iOS implementation of ICrossPlatformBacking utilize a weak reference to avoid circular references on that platform.

Issues

Helps #14664, but TBD if it fixes it.

@github-actions
Copy link
Contributor

Thank you for your pull request. We are auto-formatting your source code to follow our code guidelines.

@@ -42,6 +41,21 @@ public ContentViewGroup(Context context, IAttributeSet attrs, int defStyleAttr,
_context = context;
}

public ICrossPlatformLayout? CrossPlatformLayout
{
get; set;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure about this but I think the platform view should never have a strong reference to the virtual view.
I think the strong references should flow like this:
VirtualView/VirtualView's Properties (eg. ItemSource) --> Handler/Manager/PlatformView

Handler/Manager --> PlatformView/Native Listeners

but whenever you need the opposite direction it should be a weak reference. It's meaningless to have a platform view that the user have already lost the reference to its VirtualView/Handler.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know how to post a comment without it being a review 😅. Feel free to dismiss this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's the point of this PR, to make that weak reference possible. The old implementation was implicitly keeping a strong reference through the internal CrossPlatformMeasure/CrossPlatformArrange Funcs. This way, we have the option of making the reference a weak one (and still allow handlers to modify the CPM/CPA implementations).

The iOS implementation in this PR already uses a weak reference for this. Since we don't currently have leaks on Windows/Android, I've left this as a strong reference to avoid the extra overhead of the weak reference target check. So we could change those to weak references in the future, if we need to.

That said, I could be convinced to make all 3 platforms use weak references just for the symmetry, assuming the performance impact of the weak reference checks is small.

@jonathanpeppers @PureWeen @mattleibow any thoughts on that?

Copy link
Member

Choose a reason for hiding this comment

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

The above property is Android only, so there isn't an issue there? Really only need to be concerned about cycles on iOS/Catalyst.

Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

This looks like it is on the right track to get rid of the delegates for CrossPlatformArrange/Measure.

I would also update these tests:

Content = new VerticalStackLayout
{
new Label(),
new Button(),
new CollectionView(),
}

Content = new VerticalStackLayout
{
new Label(),
new Button(),
new CollectionView(),
}

To include a ScrollView & ContentView. In debugging these issues on iOS, I sometimes found these tests would find further problems...

@@ -42,6 +41,21 @@ public ContentViewGroup(Context context, IAttributeSet attrs, int defStyleAttr,
_context = context;
}

public ICrossPlatformLayout? CrossPlatformLayout
{
get; set;
Copy link
Member

Choose a reason for hiding this comment

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

The above property is Android only, so there isn't an issue there? Really only need to be concerned about cycles on iOS/Catalyst.

@jonathanpeppers
Copy link
Member

If this "formalizes layout concepts", should there also be a .md file that describes the design? It would go in here:

https://github.com/dotnet/maui/tree/main/docs

@rmarinho
Copy link
Member

/rebase

@Eilon Eilon added the area-layout StackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenter label Jun 1, 2023
hartez and others added 5 commits June 1, 2023 10:52
@hartez
Copy link
Contributor Author

hartez commented Jun 2, 2023

If this "formalizes layout concepts", should there also be a .md file that describes the design? It would go in here:

https://github.com/dotnet/maui/tree/main/docs

Assuming this PR gets merged and the layout docs PR gets merged, I'll update the docs to include the changes here.

# Conflicts:
#	src/Controls/src/Core/Frame/Frame.cs
#	src/Controls/src/Core/HandlerImpl/ScrollView/ScrollView.Impl.cs
#	src/Controls/src/Core/HandlerImpl/TemplatedView/TemplatedView.Impl.cs
#	src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
#	src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
#	src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
#	src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
#	src/Core/src/PublicAPI/net/PublicAPI.Unshipped.txt
#	src/Core/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt
#	src/Core/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
Copy link
Member

@jonathanpeppers jonathanpeppers left a comment

Choose a reason for hiding this comment

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

I went through the latest changes, and I like this PR over: #15193

However, I'm probably not qualified to know if the iOS/ScrollView changes are OK. Maybe we have to manually test those?

@PureWeen PureWeen merged commit 5419846 into main Jun 22, 2023
@PureWeen PureWeen deleted the formalize-virtuallayout branch June 22, 2023 21:47
@jonathanpeppers jonathanpeppers added the memory-leak 💦 Memory usage grows / objects live forever label Jul 12, 2023
@ghost
Copy link

ghost commented Jul 27, 2023

🚨 API change(s) detected @davidbritch FYI

@github-actions github-actions bot locked and limited conversation to collaborators Dec 10, 2023
@samhouts samhouts added the fixed-in-8.0.0-preview.6.8686 Look for this fix in 8.0.0-preview.6.8686! label Aug 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-layout StackLayout, GridLayout, ContentView, AbsoluteLayout, FlexLayout, ContentPresenter fixed-in-8.0.0-preview.6.8686 Look for this fix in 8.0.0-preview.6.8686! memory-leak 💦 Memory usage grows / objects live forever needs-breaking-change-doc-created platform/iOS 🍎 t/breaking 💥
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants