From 7e636f29c857fdd80f63d38d2dca1bd18f3deba2 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 28 Nov 2023 16:05:44 -0600 Subject: [PATCH] [ios] update MemoryAnalyzers and cleanup (#18449) * [ios] update MemoryAnalyzers and cleanup `MemoryAnalyzers` 0.1.0-beta.5 now warns about interfaces like: public class MyView : UIView { IFoo foo; } Since another `UIView` subclass could be assigned to `foo` at runtime, creating a circular reference -- it should be good to warn about this going forward. This is what allowed some of the leaks to slip through in a589b120. A few new warnings appeared, but I don't think they are real issues except for `src\Core\src\Platform\iOS\MauiUIContextMenuInteraction.cs`, which I think we can just remove the field. I also changed the warning code from `MA*` to `MEM*`, as there were already error codes in the `MA*` range. Lastly, I renamed `Microsoft.Extensions.targets` to `NuGetVersions.targets` as we have many packages in there beyond `Microsoft.Extensions`. We can also start tracking the `MemoryAnalyzers` version here as we start adding it to more projects. * Restore IUIContextMenuInteractionDelegate, fix race condition Context: https://github.com/dotnet/maui/pull/18449#discussion_r1379791733 Co-authored-by: Rolf Bjarne Kvinge --------- Co-authored-by: Rolf Bjarne Kvinge --- Directory.Build.targets | 2 +- ...osoft.Extensions.targets => NuGetVersions.targets} | 5 +++++ .../ResignFirstResponderTouchGestureRecognizer.iOS.cs | 2 +- src/Core/src/Core.csproj | 2 +- .../SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cs | 2 +- src/Core/src/Platform/WrapperView.cs | 6 +++++- src/Core/src/Platform/iOS/ContainerViewController.cs | 6 ++++-- src/Core/src/Platform/iOS/MauiActivityIndicator.cs | 4 +--- src/Core/src/Platform/iOS/MauiBoxView.cs | 2 +- src/Core/src/Platform/iOS/MauiCALayer.cs | 3 ++- src/Core/src/Platform/iOS/MauiCheckBox.cs | 2 +- src/Core/src/Platform/iOS/MauiImageView.cs | 2 +- src/Core/src/Platform/iOS/MauiLabel.cs | 2 +- src/Core/src/Platform/iOS/MauiPageControl.cs | 2 +- src/Core/src/Platform/iOS/MauiPicker.cs | 2 +- src/Core/src/Platform/iOS/MauiRefreshView.cs | 8 ++++---- src/Core/src/Platform/iOS/MauiScrollView.cs | 2 +- src/Core/src/Platform/iOS/MauiSearchBar.cs | 10 +++++----- src/Core/src/Platform/iOS/MauiShapeView.cs | 2 +- src/Core/src/Platform/iOS/MauiSwipeView.cs | 8 ++++---- src/Core/src/Platform/iOS/MauiTextField.cs | 6 +++--- src/Core/src/Platform/iOS/MauiTextView.cs | 6 +++--- src/Core/src/Platform/iOS/MauiTimePicker.cs | 2 +- .../Platform/iOS/MauiUIApplicationDelegate.Menu.cs | 2 ++ .../src/Platform/iOS/MauiUIApplicationDelegate.cs | 6 ++++-- .../src/Platform/iOS/MauiUIContextMenuInteraction.cs | 11 ++++++++--- src/Core/src/Platform/iOS/MauiView.cs | 2 +- src/Core/src/Platform/iOS/MauiWKWebView.cs | 4 ++-- src/Core/src/Platform/iOS/NoCaretField.cs | 2 +- .../src/Platform/iOS/PlatformTouchGraphicsView.cs | 2 +- src/Core/src/Platform/iOS/WrapperView.cs | 4 ++-- 31 files changed, 70 insertions(+), 51 deletions(-) rename eng/{Microsoft.Extensions.targets => NuGetVersions.targets} (98%) diff --git a/Directory.Build.targets b/Directory.Build.targets index e1e073a966..b6c48d5223 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -5,7 +5,7 @@ - + diff --git a/eng/Microsoft.Extensions.targets b/eng/NuGetVersions.targets similarity index 98% rename from eng/Microsoft.Extensions.targets rename to eng/NuGetVersions.targets index 108de08c3a..3e033acd17 100644 --- a/eng/Microsoft.Extensions.targets +++ b/eng/NuGetVersions.targets @@ -233,5 +233,10 @@ Update="Fizzler" Version="$(FizzlerPackageVersion)" /> + diff --git a/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/ResignFirstResponderTouchGestureRecognizer.iOS.cs b/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/ResignFirstResponderTouchGestureRecognizer.iOS.cs index 76924f93b6..83d6fe9f24 100644 --- a/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/ResignFirstResponderTouchGestureRecognizer.iOS.cs +++ b/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/ResignFirstResponderTouchGestureRecognizer.iOS.cs @@ -8,7 +8,7 @@ namespace Microsoft.Maui.Platform internal class ResignFirstResponderTouchGestureRecognizer : UITapGestureRecognizer { readonly WeakReference _targetView; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: UIViewSubclassTests.ResignFirstResponderTouchGestureRecognizer")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: UIViewSubclassTests.ResignFirstResponderTouchGestureRecognizer")] Token? _token; public ResignFirstResponderTouchGestureRecognizer(UIView targetView) : diff --git a/src/Core/src/Core.csproj b/src/Core/src/Core.csproj index 377f2112f6..b0a5c29e8d 100644 --- a/src/Core/src/Core.csproj +++ b/src/Core/src/Core.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cs b/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cs index 7953b75a24..2774774446 100644 --- a/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cs +++ b/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.iOS.cs @@ -8,7 +8,7 @@ namespace Microsoft.Maui.Handlers { public class SwipeItemButton : UIButton { - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "Proven safe in test: SwipeViewTests.ItemsDoNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "Proven safe in test: SwipeViewTests.ItemsDoNotLeak")] public event EventHandler? FrameChanged; public override CGRect Frame diff --git a/src/Core/src/Platform/WrapperView.cs b/src/Core/src/Platform/WrapperView.cs index eafb71024c..700c440d5b 100644 --- a/src/Core/src/Platform/WrapperView.cs +++ b/src/Core/src/Platform/WrapperView.cs @@ -1,11 +1,15 @@ -using Microsoft.Maui.Graphics; +using System.Diagnostics.CodeAnalysis; +using Microsoft.Maui.Graphics; namespace Microsoft.Maui.Platform { public partial class WrapperView { + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IShape is a non-NSObject in MAUI.")] IShape? _clip; + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IShadow is a non-NSObject in MAUI.")] IShadow? _shadow; + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IBorder is a non-NSObject in MAUI.")] IBorderStroke? _border; #if WINDOWS diff --git a/src/Core/src/Platform/iOS/ContainerViewController.cs b/src/Core/src/Platform/iOS/ContainerViewController.cs index e7cad69b78..a23c277b7d 100644 --- a/src/Core/src/Platform/iOS/ContainerViewController.cs +++ b/src/Core/src/Platform/iOS/ContainerViewController.cs @@ -8,14 +8,15 @@ namespace Microsoft.Maui.Platform { public class ContainerViewController : UIViewController, IReloadHandler { + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: NavigationPageTests.DoesNotLeak")] IElement? _view; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: NavigationPageTests.DoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: NavigationPageTests.DoesNotLeak")] UIView? currentPlatformView; // The handler needs this view before LoadView is called on the controller // So this is used to create the first view that the handler will use // without forcing the VC to call LoadView - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: NavigationPageTests.DoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: NavigationPageTests.DoesNotLeak")] UIView? _pendingLoadedView; public IElement? CurrentView @@ -27,6 +28,7 @@ namespace Microsoft.Maui.Platform public UIView? CurrentPlatformView => _pendingLoadedView ?? currentPlatformView; + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IMauiContext is a non-NSObject in MAUI.")] public IMauiContext? Context { get; set; } void SetView(IElement? view, bool forceRefresh = false) diff --git a/src/Core/src/Platform/iOS/MauiActivityIndicator.cs b/src/Core/src/Platform/iOS/MauiActivityIndicator.cs index 32ad6011c5..7fc1d8cd1c 100644 --- a/src/Core/src/Platform/iOS/MauiActivityIndicator.cs +++ b/src/Core/src/Platform/iOS/MauiActivityIndicator.cs @@ -43,9 +43,7 @@ namespace Microsoft.Maui.Platform base.Dispose(disposing); } - readonly WeakEventManager _weakEventManager = new(); - - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiBoxView.cs b/src/Core/src/Platform/iOS/MauiBoxView.cs index 89eac54780..ffd610978a 100644 --- a/src/Core/src/Platform/iOS/MauiBoxView.cs +++ b/src/Core/src/Platform/iOS/MauiBoxView.cs @@ -13,7 +13,7 @@ namespace Microsoft.Maui.Platform BackgroundColor = UIColor.Clear; } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiCALayer.cs b/src/Core/src/Platform/iOS/MauiCALayer.cs index b91a8b2200..c0bcdca191 100644 --- a/src/Core/src/Platform/iOS/MauiCALayer.cs +++ b/src/Core/src/Platform/iOS/MauiCALayer.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Diagnostics.CodeAnalysis; using CoreAnimation; using CoreGraphics; using Microsoft.Maui.Graphics; @@ -12,7 +13,7 @@ namespace Microsoft.Maui.Platform public class MauiCALayer : CALayer { CGRect _bounds; - + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IShape is a non-NSObject in MAUI.")] IShape? _shape; UIColor? _backgroundColor; diff --git a/src/Core/src/Platform/iOS/MauiCheckBox.cs b/src/Core/src/Platform/iOS/MauiCheckBox.cs index 1d6529efeb..b996641805 100644 --- a/src/Core/src/Platform/iOS/MauiCheckBox.cs +++ b/src/Core/src/Platform/iOS/MauiCheckBox.cs @@ -302,7 +302,7 @@ namespace Microsoft.Maui.Platform set { } } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiImageView.cs b/src/Core/src/Platform/iOS/MauiImageView.cs index 31a09f0e09..ac45dafa27 100644 --- a/src/Core/src/Platform/iOS/MauiImageView.cs +++ b/src/Core/src/Platform/iOS/MauiImageView.cs @@ -23,7 +23,7 @@ namespace Microsoft.Maui.Platform { } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiLabel.cs b/src/Core/src/Platform/iOS/MauiLabel.cs index 9a760d1fd1..5708f04f74 100644 --- a/src/Core/src/Platform/iOS/MauiLabel.cs +++ b/src/Core/src/Platform/iOS/MauiLabel.cs @@ -100,7 +100,7 @@ namespace Microsoft.Maui.Platform width: size.Width + TextInsets.Left + TextInsets.Right, height: size.Height + TextInsets.Top + TextInsets.Bottom); - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiPageControl.cs b/src/Core/src/Platform/iOS/MauiPageControl.cs index 5afe28c52b..66dfa2f845 100644 --- a/src/Core/src/Platform/iOS/MauiPageControl.cs +++ b/src/Core/src/Platform/iOS/MauiPageControl.cs @@ -146,7 +146,7 @@ namespace Microsoft.Maui.Platform } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiPicker.cs b/src/Core/src/Platform/iOS/MauiPicker.cs index 88cdbda1a2..06956ddc67 100644 --- a/src/Core/src/Platform/iOS/MauiPicker.cs +++ b/src/Core/src/Platform/iOS/MauiPicker.cs @@ -19,7 +19,7 @@ namespace Microsoft.Maui.Platform _enableActions = new HashSet(actions); } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] public UIPickerView? UIPickerView { get; set; } public override bool CanPerform(Selector action, NSObject? withSender) diff --git a/src/Core/src/Platform/iOS/MauiRefreshView.cs b/src/Core/src/Platform/iOS/MauiRefreshView.cs index 1691d8ed82..21a894bb93 100644 --- a/src/Core/src/Platform/iOS/MauiRefreshView.cs +++ b/src/Core/src/Platform/iOS/MauiRefreshView.cs @@ -15,11 +15,11 @@ namespace Microsoft.Maui.Platform bool _isRefreshing; nfloat _originalY; nfloat _refreshControlHeight; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIView _refreshControlParent; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIView? _contentView; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIRefreshControl _refreshControl; public UIRefreshControl RefreshControl => _refreshControl; @@ -199,7 +199,7 @@ namespace Microsoft.Maui.Platform this.GetNavigationController()?.NavigationBar?.PrefersLargeTitles ?? true; #pragma warning restore CA1416 - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiScrollView.cs b/src/Core/src/Platform/iOS/MauiScrollView.cs index 7b26b24480..00c1ca3d55 100644 --- a/src/Core/src/Platform/iOS/MauiScrollView.cs +++ b/src/Core/src/Platform/iOS/MauiScrollView.cs @@ -19,7 +19,7 @@ namespace Microsoft.Maui.Platform base.ScrollRectToVisible(rect, animated); } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiSearchBar.cs b/src/Core/src/Platform/iOS/MauiSearchBar.cs index a02ddd153e..4967c9b35b 100644 --- a/src/Core/src/Platform/iOS/MauiSearchBar.cs +++ b/src/Core/src/Platform/iOS/MauiSearchBar.cs @@ -33,7 +33,7 @@ namespace Microsoft.Maui.Platform // Native Changed doesn't fire when the Text Property is set in code // We use this event as a way to fire changes whenever the Text changes // via code or user interaction. - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] public event EventHandler? TextSetOrChanged; public override string? Text @@ -52,9 +52,9 @@ namespace Microsoft.Maui.Platform } } - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] internal event EventHandler? OnMovedToWindow; - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] internal event EventHandler? EditingChanged; public override void WillMoveToWindow(UIWindow? window) @@ -74,13 +74,13 @@ namespace Microsoft.Maui.Platform OnMovedToWindow?.Invoke(this, EventArgs.Empty); } - [UnconditionalSuppressMessage("Memory", "MA0003", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] + [UnconditionalSuppressMessage("Memory", "MEM0003", Justification = "FIXME: https://github.com/dotnet/maui/pull/16383")] void OnEditingChanged(object? sender, EventArgs e) { EditingChanged?.Invoke(this, EventArgs.Empty); } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiShapeView.cs b/src/Core/src/Platform/iOS/MauiShapeView.cs index c682e5dcc5..774e058c85 100644 --- a/src/Core/src/Platform/iOS/MauiShapeView.cs +++ b/src/Core/src/Platform/iOS/MauiShapeView.cs @@ -13,7 +13,7 @@ namespace Microsoft.Maui.Platform BackgroundColor = UIColor.Clear; } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiSwipeView.cs b/src/Core/src/Platform/iOS/MauiSwipeView.cs index 6e0ca75e88..af34f26141 100644 --- a/src/Core/src/Platform/iOS/MauiSwipeView.cs +++ b/src/Core/src/Platform/iOS/MauiSwipeView.cs @@ -17,13 +17,13 @@ namespace Microsoft.Maui.Platform readonly SwipeRecognizerProxy _proxy; readonly Dictionary _swipeItems; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] readonly UITapGestureRecognizer _tapGestureRecognizer; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] readonly UIPanGestureRecognizer _panGestureRecognizer; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIView _contentView; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIStackView _actionView; SwipeTransitionMode _swipeTransitionMode; SwipeDirection? _swipeDirection; diff --git a/src/Core/src/Platform/iOS/MauiTextField.cs b/src/Core/src/Platform/iOS/MauiTextField.cs index 350863da49..f1bee62410 100644 --- a/src/Core/src/Platform/iOS/MauiTextField.cs +++ b/src/Core/src/Platform/iOS/MauiTextField.cs @@ -66,7 +66,7 @@ namespace Microsoft.Maui.Platform } } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { @@ -80,9 +80,9 @@ namespace Microsoft.Maui.Platform _movedToWindow?.Invoke(this, EventArgs.Empty); } - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] public event EventHandler? TextPropertySet; - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] internal event EventHandler? SelectionChanged; } } \ No newline at end of file diff --git a/src/Core/src/Platform/iOS/MauiTextView.cs b/src/Core/src/Platform/iOS/MauiTextView.cs index c40126a03b..7942b31b86 100644 --- a/src/Core/src/Platform/iOS/MauiTextView.cs +++ b/src/Core/src/Platform/iOS/MauiTextView.cs @@ -10,7 +10,7 @@ namespace Microsoft.Maui.Platform { public class MauiTextView : UITextView, IUIViewLifeCycleEvents { - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] readonly MauiLabel _placeholderLabel; nfloat? _defaultPlaceholderSize; @@ -37,7 +37,7 @@ namespace Microsoft.Maui.Platform // Native Changed doesn't fire when the Text Property is set in code // We use this event as a way to fire changes whenever the Text changes // via code or user interaction. - [UnconditionalSuppressMessage("Memory", "MA0001", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0001", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] public event EventHandler? TextSetOrChanged; public string? PlaceholderText @@ -182,7 +182,7 @@ namespace Microsoft.Maui.Platform value?.PointSize ?? _defaultPlaceholderSize.Value); } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiTimePicker.cs b/src/Core/src/Platform/iOS/MauiTimePicker.cs index 977f4810c9..e5cdbfa34c 100644 --- a/src/Core/src/Platform/iOS/MauiTimePicker.cs +++ b/src/Core/src/Platform/iOS/MauiTimePicker.cs @@ -7,7 +7,7 @@ namespace Microsoft.Maui.Platform { public class MauiTimePicker : NoCaretField { - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] readonly UIDatePicker _picker; #if !MACCATALYST diff --git a/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs b/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs index bbc8524190..e212a0a41e 100644 --- a/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs +++ b/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; using Foundation; using Microsoft.Extensions.DependencyInjection; @@ -12,6 +13,7 @@ namespace Microsoft.Maui { public partial class MauiUIApplicationDelegate { + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "There is a single MauiUIApplicationDelegate")] internal IUIMenuBuilder? MenuBuilder { get; private set; } [SupportedOSPlatform("ios13.0")] diff --git a/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.cs b/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.cs index b8d0c1e006..a25ae1509e 100644 --- a/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.cs +++ b/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.cs @@ -17,10 +17,12 @@ namespace Microsoft.Maui internal const string MauiSceneConfigurationKey = "__MAUI_DEFAULT_SCENE_CONFIGURATION__"; internal const string GetConfigurationSelectorName = "application:configurationForConnectingSceneSession:options:"; + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IMauiContext is a non-NSObject in MAUI.")] IMauiContext _applicationContext = null!; + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IServiceProvider is a non-NSObject from Microsoft.Extensions.DependencyInjection.")] IServiceProvider? _services; - + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "IApplication is a non-NSObject in MAUI.")] IApplication? _application; protected MauiUIApplicationDelegate() : base() @@ -163,7 +165,7 @@ namespace Microsoft.Maui _services?.InvokeLifecycleEvents(del => del(application, completionHandler)); } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "There can only be one MauiUIApplicationDelegate.")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "There can only be one MauiUIApplicationDelegate.")] public static MauiUIApplicationDelegate Current { get; private set; } = null!; [Export("window")] diff --git a/src/Core/src/Platform/iOS/MauiUIContextMenuInteraction.cs b/src/Core/src/Platform/iOS/MauiUIContextMenuInteraction.cs index ddc36c4b3d..815993a882 100644 --- a/src/Core/src/Platform/iOS/MauiUIContextMenuInteraction.cs +++ b/src/Core/src/Platform/iOS/MauiUIContextMenuInteraction.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; using CoreGraphics; using Foundation; @@ -14,15 +15,19 @@ namespace Microsoft.Maui.Platform WeakReference _handler; // Store a reference to the platform delegate so that it is not garbage collected - IUIContextMenuInteractionDelegate? _uiContextMenuInteractionDelegate; + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Delegate is weak on Objective-C side")] + readonly IUIContextMenuInteractionDelegate? _uiContextMenuInteractionDelegate; public MauiUIContextMenuInteraction(IElementHandler handler) - : base(new FlyoutUIContextMenuInteractionDelegate()) + : base(CreateDelegate (out var del)) { - _uiContextMenuInteractionDelegate = Delegate; + _uiContextMenuInteractionDelegate = del; _handler = new WeakReference(handler); } + static IUIContextMenuInteractionDelegate CreateDelegate (out IUIContextMenuInteractionDelegate del) => + del = new FlyoutUIContextMenuInteractionDelegate(); + public UIContextMenuConfiguration? GetConfigurationForMenu() { var contextFlyout = (Handler?.VirtualView as IContextFlyoutElement)?.ContextFlyout; diff --git a/src/Core/src/Platform/iOS/MauiView.cs b/src/Core/src/Platform/iOS/MauiView.cs index 743083d945..976a742f66 100644 --- a/src/Core/src/Platform/iOS/MauiView.cs +++ b/src/Core/src/Platform/iOS/MauiView.cs @@ -158,7 +158,7 @@ namespace Microsoft.Maui.Platform return null; } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler? IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/MauiWKWebView.cs b/src/Core/src/Platform/iOS/MauiWKWebView.cs index ae3b9c35d3..196986708e 100644 --- a/src/Core/src/Platform/iOS/MauiWKWebView.cs +++ b/src/Core/src/Platform/iOS/MauiWKWebView.cs @@ -13,7 +13,7 @@ namespace Microsoft.Maui.Platform { public class MauiWKWebView : WKWebView, IWebViewDelegate, IUIViewLifeCycleEvents { - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Used to persist cookies across WebView instances. Not a leak.")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Used to persist cookies across WebView instances. Not a leak.")] static WKProcessPool? SharedPool; string? _pendingUrl; @@ -200,7 +200,7 @@ namespace Microsoft.Maui.Platform return false; } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/NoCaretField.cs b/src/Core/src/Platform/iOS/NoCaretField.cs index daea843eec..500c2ef0c8 100644 --- a/src/Core/src/Platform/iOS/NoCaretField.cs +++ b/src/Core/src/Platform/iOS/NoCaretField.cs @@ -20,7 +20,7 @@ namespace Microsoft.Maui.Platform return RectangleF.Empty; } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler? IUIViewLifeCycleEvents.MovedToWindow { diff --git a/src/Core/src/Platform/iOS/PlatformTouchGraphicsView.cs b/src/Core/src/Platform/iOS/PlatformTouchGraphicsView.cs index cc97f442f5..6f50643f0c 100644 --- a/src/Core/src/Platform/iOS/PlatformTouchGraphicsView.cs +++ b/src/Core/src/Platform/iOS/PlatformTouchGraphicsView.cs @@ -11,7 +11,7 @@ namespace Microsoft.Maui.Platform { readonly UIHoverGestureRecognizerProxy _proxy; WeakReference? _graphicsView; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "Proven safe in test: MemoryTests.HandlerDoesNotLeak")] UIHoverGestureRecognizer? _hoverGesture; RectF _rect; bool _pressedContained; diff --git a/src/Core/src/Platform/iOS/WrapperView.cs b/src/Core/src/Platform/iOS/WrapperView.cs index 754cda66e3..da4a3d350e 100644 --- a/src/Core/src/Platform/iOS/WrapperView.cs +++ b/src/Core/src/Platform/iOS/WrapperView.cs @@ -14,7 +14,7 @@ namespace Microsoft.Maui.Platform CAShapeLayer? _maskLayer; CAShapeLayer? _backgroundMaskLayer; CAShapeLayer? _shadowLayer; - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = "_borderView is a SubView")] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = "_borderView is a SubView")] UIView? _borderView; public WrapperView() @@ -277,7 +277,7 @@ namespace Microsoft.Maui.Platform return Layer; } - [UnconditionalSuppressMessage("Memory", "MA0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] + [UnconditionalSuppressMessage("Memory", "MEM0002", Justification = IUIViewLifeCycleEvents.UnconditionalSuppressMessage)] EventHandler? _movedToWindow; event EventHandler? IUIViewLifeCycleEvents.MovedToWindow {