Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ios] fix memory leak in Image
Browse files Browse the repository at this point in the history
Context: dotnet#14664 (comment)

`Image` has two different "cycles" on iOS:

* `ImageHandler` -> `MauiImageView` -> `ImageHandler`

  * via the `WindowChanged` event

* `ImageHandler` -> `ImageSourcePartLoader` -> `ImageHandler`

    * via `Handler`, `Func<IImageSourcePart?>`, and `Action<PlatformImage?>`

This causes any `MauiImageView` to live forever.

To solve these issues:

* Get rid of the `MauiImageView.WindowChanged` event, and use a
`WeakReference` to the handler instead.

* `ImageSourcePartLoader` now only has a `WeakReference` to the handler.

* This requires a new `ISetImageHandler` interface to be used by
several handler types involving images.

Hopefully the changes here are using `[Obsolete]` correctly to make
things backwards compatible & less breaking changes.

Unsure yet if this fully solves dotnet#14664, but at least one part of it.
jonathanpeppers committed May 15, 2023
1 parent 45060ca commit 878e6cf
Showing 37 changed files with 152 additions and 65 deletions.
40 changes: 40 additions & 0 deletions src/Controls/tests/DeviceTests/Elements/Image/ImageTests.cs
Original file line number Diff line number Diff line change
@@ -46,5 +46,45 @@ await InvokeOnMainThreadAsync(async () =>
await handler.ToPlatform().AssertContainsColor(Colors.Red, MauiContext);
});
}

[Fact("Image Does Not Leak")]
public async Task DoesNotLeak()
{
SetupBuilder();
WeakReference platformViewReference = null;
WeakReference handlerReference = null;

await InvokeOnMainThreadAsync(async () =>
{
var layout = new VerticalStackLayout();
var image = new Image
{
Background = Colors.Black,
Source = "red.png",
};
layout.Add(image);

var handler = CreateHandler<LayoutHandler>(layout);
handlerReference = new WeakReference(image.Handler);
platformViewReference = new WeakReference(image.Handler.PlatformView);
await image.Wait();
});

Assert.NotNull(handlerReference);
Assert.NotNull(platformViewReference);

// Several GCs required on iOS
for (int i = 0; i < 5; i++)
{
if (!handlerReference.IsAlive && !platformViewReference.IsAlive)
break;
await Task.Yield();
GC.Collect();
GC.WaitForPendingFinalizers();
}

Assert.False(handlerReference.IsAlive, "Handler should not be alive!");
Assert.False(platformViewReference.IsAlive, "PlatformView should not be alive!");
}
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.Android.cs
Original file line number Diff line number Diff line change
@@ -121,7 +121,7 @@ public static Task MapImageSourceAsync(IButtonHandler handler, IImage image)
return handler.ImageSourceLoader.UpdateImageSourceAsync();
}

void OnSetImageSource(Drawable? obj)
void ISetImageHandler.SetImageSource(Drawable? obj)
{
PlatformView.Icon = obj;
}
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.Standard.cs
Original file line number Diff line number Diff line change
@@ -16,6 +16,6 @@ public static void MapFont(IButtonHandler handler, ITextStyle button) { }
public static void MapPadding(IButtonHandler handler, IButton button) { }
public static void MapImageSource(IButtonHandler handler, IImage image) { }

void OnSetImageSource(object? obj) { }
void ISetImageHandler.SetImageSource(object? obj) { }
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.Tizen.cs
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ void OnButtonPressed(object? sender, EventArgs e)
VirtualView?.Pressed();
}

void OnSetImageSource(MauiImageSource? image)
void ISetImageHandler.SetImageSource(MauiImageSource? image)
{
if (image == null)
return;
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.Windows.cs
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ public static void MapImageSource(IButtonHandler handler, IImage image) =>
.UpdateImageSourceAsync()
.FireAndForget(handler);

void OnSetImageSource(ImageSource? platformImageSource)
void ISetImageHandler.SetImageSource(ImageSource? platformImageSource)
{
PlatformView.UpdateImageSource(platformImageSource);
}
4 changes: 2 additions & 2 deletions src/Core/src/Handlers/Button/ButtonHandler.cs
Original file line number Diff line number Diff line change
@@ -12,11 +12,11 @@

namespace Microsoft.Maui.Handlers
{
public partial class ButtonHandler : IButtonHandler
public partial class ButtonHandler : IButtonHandler, ISetImageHandler
{
ImageSourcePartLoader? _imageSourcePartLoader;
public ImageSourcePartLoader ImageSourceLoader =>
_imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => (VirtualView as IImageButton), OnSetImageSource);
_imageSourcePartLoader ??= new ImageSourcePartLoader(this);

public static IPropertyMapper<IImage, IButtonHandler> ImageButtonMapper = new PropertyMapper<IImage, IButtonHandler>()
{
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Button/ButtonHandler.iOS.cs
Original file line number Diff line number Diff line change
@@ -129,7 +129,7 @@ public static void MapFormatting(IButtonHandler handler, IText button)
handler.PlatformView?.UpdateCharacterSpacing(button);
}

void OnSetImageSource(UIImage? image)
void ISetImageHandler.SetImageSource(UIImage? image)
{
if (image != null)
{
20 changes: 20 additions & 0 deletions src/Core/src/Handlers/Image/ISetImageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#if __IOS__ || MACCATALYST
using PlatformImage = UIKit.UIImage;
#elif MONOANDROID
using PlatformImage = Android.Graphics.Drawables.Drawable;
#elif WINDOWS
using PlatformImage = Microsoft.UI.Xaml.Media.ImageSource;
#elif TIZEN
using PlatformImage = Microsoft.Maui.Platform.MauiImageSource;
#elif (NETSTANDARD || !PLATFORM) || (NET6_0_OR_GREATER && !IOS && !ANDROID && !TIZEN)
using PlatformImage = System.Object;
#endif

namespace Microsoft.Maui
{
public interface ISetImageHandler : IElementHandler
{
void SetImageSource(PlatformImage? obj);
}
}

2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Image/ImageHandler.Android.cs
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ public static void MapSource(IImageHandler handler, IImage image) =>
public static Task MapSourceAsync(IImageHandler handler, IImage image) =>
handler.SourceLoader.UpdateImageSourceAsync();

void OnSetImageSource(Drawable? obj) =>
void ISetImageHandler.SetImageSource(Drawable? obj) =>
PlatformView.SetImageDrawable(obj);

public override void PlatformArrange(Graphics.Rect frame)
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Image/ImageHandler.Standard.cs
Original file line number Diff line number Diff line change
@@ -8,6 +8,6 @@ public partial class ImageHandler : ViewHandler<IImage, object>
public static void MapAspect(IImageHandler handler, IImage image) { }
public static void MapIsAnimationPlaying(IImageHandler handler, IImage image) { }
public static void MapSource(IImageHandler handler, IImage image) { }
void OnSetImageSource(object? obj) => throw new NotImplementedException();
void ISetImageHandler.SetImageSource(object? obj) => throw new NotImplementedException();
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Image/ImageHandler.Tizen.cs
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ public static void MapSource(IImageHandler handler, IImage image) =>
public static Task MapSourceAsync(IImageHandler handler, IImage image) =>
handler.SourceLoader.UpdateImageSourceAsync();

void OnSetImageSource(MauiImageSource? obj)
void ISetImageHandler.SetImageSource(MauiImageSource? obj)
{
if (obj == null)
return;
2 changes: 1 addition & 1 deletion src/Core/src/Handlers/Image/ImageHandler.Windows.cs
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ public static void MapSource(IImageHandler handler, IImage image) =>
public static Task MapSourceAsync(IImageHandler handler, IImage image) =>
handler.SourceLoader.UpdateImageSourceAsync();

void OnSetImageSource(ImageSource? obj) =>
void ISetImageHandler.SetImageSource(ImageSource? obj) =>
PlatformView.Source = obj;
}
}
4 changes: 2 additions & 2 deletions src/Core/src/Handlers/Image/ImageHandler.cs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@

namespace Microsoft.Maui.Handlers
{
public partial class ImageHandler : IImageHandler
public partial class ImageHandler : IImageHandler, ISetImageHandler
{
public static IPropertyMapper<IImage, IImageHandler> Mapper = new PropertyMapper<IImage, IImageHandler>(ViewHandler.ViewMapper)
{
@@ -32,7 +32,7 @@ public partial class ImageHandler : IImageHandler

ImageSourcePartLoader? _imageSourcePartLoader;
public ImageSourcePartLoader SourceLoader =>
_imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
_imageSourcePartLoader ??= new ImageSourcePartLoader(this);

public ImageHandler() : base(Mapper)
{
17 changes: 3 additions & 14 deletions src/Core/src/Handlers/Image/ImageHandler.iOS.cs
Original file line number Diff line number Diff line change
@@ -9,23 +9,12 @@ namespace Microsoft.Maui.Handlers
{
public partial class ImageHandler : ViewHandler<IImage, UIImageView>
{
protected override UIImageView CreatePlatformView() => new MauiImageView();

protected override void ConnectHandler(UIImageView platformView)
{
base.ConnectHandler(platformView);

if (PlatformView is MauiImageView imageView)
imageView.WindowChanged += OnWindowChanged;
}
protected override UIImageView CreatePlatformView() => new MauiImageView(this);

protected override void DisconnectHandler(UIImageView platformView)
{
base.DisconnectHandler(platformView);

if (platformView is MauiImageView imageView)
imageView.WindowChanged -= OnWindowChanged;

SourceLoader.Reset();
}

@@ -52,10 +41,10 @@ public static void MapSource(IImageHandler handler, IImage image) =>
public static Task MapSourceAsync(IImageHandler handler, IImage image) =>
handler.SourceLoader.UpdateImageSourceAsync();

void OnSetImageSource(UIImage? obj) =>
void ISetImageHandler.SetImageSource(UIImage? obj) =>
PlatformView.Image = obj;

void OnWindowChanged(object? sender, EventArgs e)
internal void NotifyWindowChanged()
{
if (SourceLoader.SourceManager.IsResolutionDependent)
UpdateValue(nameof(IImage.Source));
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ protected override ShapeableImageView CreatePlatformView()
return platformView;
}

void OnSetImageSource(Drawable? obj)
void ISetImageHandler.SetImageSource(Drawable? obj)
{
PlatformView.SetImageDrawable(obj);
}
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ public static void MapStrokeThickness(IImageButtonHandler handler, IButtonStroke
public static void MapCornerRadius(IImageButtonHandler handler, IButtonStroke buttonStroke) { }
public static void MapPadding(IImageButtonHandler handler, IImageButton imageButton) { }

void OnSetImageSource(object? obj)
void ISetImageHandler.SetImageSource(object? obj)
{
throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ void OnClicked(object? sender, EventArgs e)
VirtualView?.Clicked();
}

void OnSetImageSource(MauiImageSource? img)
void ISetImageHandler.SetImageSource(MauiImageSource? img)
{
if (img == null)
return;
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ public static void MapPadding(IImageButtonHandler handler, IImageButton imageBut
(handler.PlatformView as Button)?.UpdatePadding(imageButton);
}

void OnSetImageSource(ImageSource? nativeImageSource)
void ISetImageHandler.SetImageSource(ImageSource? nativeImageSource)
{
PlatformView.UpdateImageSource(nativeImageSource);
}
4 changes: 2 additions & 2 deletions src/Core/src/Handlers/ImageButton/ImageButtonHandler.cs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@

namespace Microsoft.Maui.Handlers
{
public partial class ImageButtonHandler : IImageButtonHandler
public partial class ImageButtonHandler : IImageButtonHandler, ISetImageHandler
{
public static IPropertyMapper<IImage, IImageHandler> ImageMapper = new PropertyMapper<IImage, IImageHandler>(ImageHandler.Mapper);

@@ -44,7 +44,7 @@ public partial class ImageButtonHandler : IImageButtonHandler

ImageSourcePartLoader? _imageSourcePartLoader;
public ImageSourcePartLoader SourceLoader =>
_imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
_imageSourcePartLoader ??= new ImageSourcePartLoader(this);

public ImageButtonHandler() : base(Mapper)
{
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ protected override UIButton CreatePlatformView()
return platformView;
}

void OnSetImageSource(UIImage? obj)
void ISetImageHandler.SetImageSource(UIImage? obj)
{
PlatformView.SetImage(obj?.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal), UIControlState.Normal);
PlatformView.HorizontalAlignment = UIControlContentHorizontalAlignment.Fill;
Original file line number Diff line number Diff line change
@@ -133,7 +133,7 @@ void UpdateSize()
var icons = textView.GetCompoundDrawables();
if (icons.Length > 1 && icons[1] != null)
{
OnSetImageSource(icons[1]);
((ISetImageHandler)this).SetImageSource(icons[1]);
}
}

@@ -143,7 +143,7 @@ void UpdateSize()
PlatformView.SetPadding(0, buttonPadding, 0, buttonPadding);
}

void OnSetImageSource(Drawable? drawable)
void ISetImageHandler.SetImageSource(Drawable? drawable)
{
if (drawable != null)
{
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ public static void MapBackground(ISwipeItemMenuItemHandler handler, ISwipeItemMe

public static void MapVisibility(ISwipeItemMenuItemHandler handler, ISwipeItemMenuItem view) { }

void OnSetImageSource(object? obj)
void ISetImageHandler.SetImageSource(object? obj)
{
throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ public static void MapVisibility(ISwipeItemMenuItemHandler handler, ISwipeItemMe

}

void OnSetImageSource(MauiImageSource? obj)
void ISetImageHandler.SetImageSource(MauiImageSource? obj)
{
if (obj != null)
PlatformView.Icon.ResourceUrl = obj.ResourceUrl;
Original file line number Diff line number Diff line change
@@ -15,6 +15,9 @@
namespace Microsoft.Maui.Handlers
{
public partial class SwipeItemMenuItemHandler : ISwipeItemMenuItemHandler
#if !WINDOWS
, ISetImageHandler
#endif
{
public static IPropertyMapper<ISwipeItemMenuItem, ISwipeItemMenuItemHandler> Mapper =
new PropertyMapper<ISwipeItemMenuItem, ISwipeItemMenuItemHandler>(ViewHandler.ElementMapper)
@@ -56,7 +59,7 @@ protected SwipeItemMenuItemHandler(IPropertyMapper? mapper, CommandMapper? comma
#if !WINDOWS
ImageSourcePartLoader? _imageSourcePartLoader;
public ImageSourcePartLoader SourceLoader =>
_imageSourcePartLoader ??= new ImageSourcePartLoader(this, () => VirtualView, OnSetImageSource);
_imageSourcePartLoader ??= new ImageSourcePartLoader(this);


public static void MapSource(ISwipeItemMenuItemHandler handler, ISwipeItemMenuItem image) =>
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ void OnSwipeItemFrameChanged(object? sender, EventArgs e)
swipeItemMenuItemHandler.UpdateValue(nameof(ISwipeItemMenuItem.Source));
}

void OnSetImageSource(UIImage? image)
void ISetImageHandler.SetImageSource(UIImage? image)
{
if (PlatformView == null || PlatformView.Frame == CGRect.Empty)
return;
35 changes: 15 additions & 20 deletions src/Core/src/Platform/ImageSourcePartLoader.cs
Original file line number Diff line number Diff line change
@@ -23,48 +23,43 @@ namespace Microsoft.Maui.Platform
{
public partial class ImageSourcePartLoader
{
#if IOS || ANDROID || WINDOWS || TIZEN
IImageSourceServiceProvider? _imageSourceServiceProvider;
IImageSourceServiceProvider ImageSourceServiceProvider =>
_imageSourceServiceProvider ??= Handler.GetRequiredService<IImageSourceServiceProvider>();
#endif

readonly Func<IImageSourcePart?> _imageSourcePart;
Action<PlatformImage?>? SetImage { get; }
PlatformView? PlatformView => Handler.PlatformView as PlatformView;
readonly WeakReference<ISetImageHandler> _handler;

internal ImageSourceServiceResultManager SourceManager { get; } = new ImageSourceServiceResultManager();

IElementHandler Handler { get; }

public ImageSourcePartLoader(
IElementHandler handler,
Func<IImageSourcePart?> imageSourcePart,
Action<PlatformImage?> setImage)
[Obsolete("To be removed in a future release")]
public ImageSourcePartLoader(IElementHandler handler, Func<IImageSourcePart?> imageSourcePart, Action<PlatformImage?> setImage)
: this((ISetImageHandler)handler)
{
Handler = handler;
_imageSourcePart = imageSourcePart;

SetImage = setImage;
}

public ImageSourcePartLoader(ISetImageHandler handler) => _handler = new(handler);

public void Reset()
{
SourceManager.Reset();
}

public async Task UpdateImageSourceAsync()
{
if (PlatformView is null)
if (!_handler.TryGetTarget(out var handler) || handler.PlatformView is not PlatformView platformView)
{
return;
}

var token = this.SourceManager.BeginLoad();
var imageSource = _imageSourcePart();
var imageSource = handler.VirtualView as IImageSourcePart;

if (imageSource?.Source is not null)
{
#if __IOS__ || __ANDROID__ || WINDOWS || TIZEN
var result = await imageSource.UpdateSourceAsync(PlatformView, ImageSourceServiceProvider, SetImage!, token)
#if IOS || ANDROID || WINDOWS || TIZEN
_imageSourceServiceProvider ??= handler.GetRequiredService<IImageSourceServiceProvider>();

var result = await imageSource.UpdateSourceAsync(platformView, _imageSourceServiceProvider, handler.SetImageSource, token)
.ConfigureAwait(false);

SourceManager.CompleteLoad(result);
@@ -74,7 +69,7 @@ public async Task UpdateImageSourceAsync()
}
else
{
SetImage?.Invoke(null);
handler.SetImageSource(null);
}
}
}
22 changes: 19 additions & 3 deletions src/Core/src/Platform/iOS/MauiImageView.cs
Original file line number Diff line number Diff line change
@@ -7,18 +7,34 @@ namespace Microsoft.Maui.Platform
{
public class MauiImageView : UIImageView
{
WeakReference<ImageHandler>? _handler;

public MauiImageView(ImageHandler handler) => _handler = new WeakReference<ImageHandler>(handler);

[Obsolete("To be removed in a future release")]
public MauiImageView()
{
}

[Obsolete("To be removed in a future release")]
public MauiImageView(CGRect frame)
: base(frame)
{
}

public override void MovedToWindow() =>
WindowChanged?.Invoke(this, EventArgs.Empty);
public override void MovedToWindow()
{
if (_handler is not null && _handler.TryGetTarget(out var handler))
{
handler.NotifyWindowChanged();
}
}

public event EventHandler? WindowChanged;
[Obsolete("To be removed in a future release")]
public event EventHandler? WindowChanged
{
add { }
remove { }
}
}
}
3 changes: 3 additions & 0 deletions src/Core/src/PublicAPI/net-android/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -12,7 +12,10 @@ Microsoft.Maui.ICommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(Android.Graphics.Drawables.Drawable? obj) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.Platform.ShapeExtensions
Microsoft.Maui.PlatformContentViewGroup
Microsoft.Maui.PlatformContentViewGroup.PlatformContentViewGroup(Android.Content.Context? context) -> void
1 change: 0 additions & 1 deletion src/Core/src/PublicAPI/net-ios/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -2048,7 +2048,6 @@ override Microsoft.Maui.Handlers.GraphicsViewHandler.DisconnectHandler(Microsoft
override Microsoft.Maui.Handlers.ImageButtonHandler.ConnectHandler(UIKit.UIButton! platformView) -> void
override Microsoft.Maui.Handlers.ImageButtonHandler.CreatePlatformView() -> UIKit.UIButton!
override Microsoft.Maui.Handlers.ImageButtonHandler.DisconnectHandler(UIKit.UIButton! platformView) -> void
override Microsoft.Maui.Handlers.ImageHandler.ConnectHandler(UIKit.UIImageView! platformView) -> void
override Microsoft.Maui.Handlers.ImageHandler.CreatePlatformView() -> UIKit.UIImageView!
override Microsoft.Maui.Handlers.ImageHandler.DisconnectHandler(UIKit.UIImageView! platformView) -> void
override Microsoft.Maui.Handlers.ImageHandler.NeedsContainer.get -> bool
4 changes: 4 additions & 0 deletions src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -12,9 +12,13 @@ Microsoft.Maui.ICommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(UIKit.UIImage? obj) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.LifecycleEvents.iOSLifecycle.PerformFetch
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.Platform.KeyboardAutoManagerScroll
Microsoft.Maui.Platform.MauiImageView.MauiImageView(Microsoft.Maui.Handlers.ImageHandler! handler) -> void
Microsoft.Maui.SizeRequest.Equals(Microsoft.Maui.SizeRequest other) -> bool
Microsoft.Maui.Platform.MauiScrollView
Microsoft.Maui.Platform.MauiScrollView.MauiScrollView() -> void
Original file line number Diff line number Diff line change
@@ -2047,7 +2047,6 @@ override Microsoft.Maui.Handlers.GraphicsViewHandler.DisconnectHandler(Microsoft
override Microsoft.Maui.Handlers.ImageButtonHandler.ConnectHandler(UIKit.UIButton! platformView) -> void
override Microsoft.Maui.Handlers.ImageButtonHandler.CreatePlatformView() -> UIKit.UIButton!
override Microsoft.Maui.Handlers.ImageButtonHandler.DisconnectHandler(UIKit.UIButton! platformView) -> void
override Microsoft.Maui.Handlers.ImageHandler.ConnectHandler(UIKit.UIImageView! platformView) -> void
override Microsoft.Maui.Handlers.ImageHandler.CreatePlatformView() -> UIKit.UIImageView!
override Microsoft.Maui.Handlers.ImageHandler.DisconnectHandler(UIKit.UIImageView! platformView) -> void
override Microsoft.Maui.Handlers.ImageHandler.NeedsContainer.get -> bool
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@ Microsoft.Maui.ICommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(UIKit.UIImage? obj) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.Platform.MauiImageView.MauiImageView(Microsoft.Maui.Handlers.ImageHandler! handler) -> void
Microsoft.Maui.Platform.MauiView.CacheMeasureConstraints(double widthConstraint, double heightConstraint) -> void
Microsoft.Maui.Platform.MauiView.InvalidateConstraintsCache() -> void
Microsoft.Maui.Platform.MauiView.IsMeasureValid(double widthConstraint, double heightConstraint) -> bool
3 changes: 3 additions & 0 deletions src/Core/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -11,6 +11,9 @@ Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, Syste
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.SizeRequest.Equals(Microsoft.Maui.SizeRequest other) -> bool
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(Microsoft.Maui.Platform.MauiImageSource? obj) -> void
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
override Microsoft.Maui.Layouts.FlexBasis.Equals(object? obj) -> bool
override Microsoft.Maui.Layouts.FlexBasis.GetHashCode() -> int
override Microsoft.Maui.SizeRequest.Equals(object? obj) -> bool
3 changes: 3 additions & 0 deletions src/Core/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@ Microsoft.Maui.CommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler,
Microsoft.Maui.FocusRequest.FocusRequest() -> void
Microsoft.Maui.IApplication.UserAppTheme.get -> Microsoft.Maui.ApplicationModel.AppTheme
Microsoft.Maui.Hosting.MauiApp.DisposeAsync() -> System.Threading.Tasks.ValueTask
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(Microsoft.UI.Xaml.Media.ImageSource? obj) -> void
Microsoft.Maui.IWindow.TitleBarDragRectangles.get -> Microsoft.Maui.Graphics.Rect[]?
Microsoft.Maui.ICommandMapper
Microsoft.Maui.ICommandMapper.GetCommand(string! key) -> System.Action<Microsoft.Maui.IElementHandler!, Microsoft.Maui.IElement!, object?>?
@@ -11,6 +13,7 @@ Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.Platform.MauiWebView.MauiWebView(Microsoft.Maui.Handlers.WebViewHandler! handler) -> void
Microsoft.Maui.SizeRequest.Equals(Microsoft.Maui.SizeRequest other) -> bool
override Microsoft.Maui.Handlers.ContentViewHandler.DisconnectHandler(Microsoft.Maui.Platform.ContentPanel! platformView) -> void
3 changes: 3 additions & 0 deletions src/Core/src/PublicAPI/net/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -9,7 +9,10 @@ Microsoft.Maui.ICommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(object? obj) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.SizeRequest.Equals(Microsoft.Maui.SizeRequest other) -> bool
override Microsoft.Maui.Layouts.FlexBasis.Equals(object? obj) -> bool
override Microsoft.Maui.Layouts.FlexBasis.GetHashCode() -> int
3 changes: 3 additions & 0 deletions src/Core/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -9,7 +9,10 @@ Microsoft.Maui.ICommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(object? obj) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.SizeRequest.Equals(Microsoft.Maui.SizeRequest other) -> bool
override Microsoft.Maui.Layouts.FlexBasis.Equals(object? obj) -> bool
override Microsoft.Maui.Layouts.FlexBasis.GetHashCode() -> int
3 changes: 3 additions & 0 deletions src/Core/src/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -9,7 +9,10 @@ Microsoft.Maui.ICommandMapper.Invoke(Microsoft.Maui.IElementHandler! viewHandler
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView, object?>! action) -> void
Microsoft.Maui.ICommandMapper<TVirtualView, TViewHandler>.Add(string! key, System.Action<TViewHandler, TVirtualView>! action) -> void
Microsoft.Maui.ISetImageHandler
Microsoft.Maui.ISetImageHandler.SetImageSource(object? obj) -> void
Microsoft.Maui.Layouts.FlexBasis.Equals(Microsoft.Maui.Layouts.FlexBasis other) -> bool
Microsoft.Maui.Platform.ImageSourcePartLoader.ImageSourcePartLoader(Microsoft.Maui.ISetImageHandler! handler) -> void
Microsoft.Maui.SizeRequest.Equals(Microsoft.Maui.SizeRequest other) -> bool
override Microsoft.Maui.Layouts.FlexBasis.Equals(object? obj) -> bool
override Microsoft.Maui.Layouts.FlexBasis.GetHashCode() -> int

0 comments on commit 878e6cf

Please sign in to comment.