[ios] update MemoryAnalyzers and cleanup by jonathanpeppers · Pull Request #18449 · dotnet/maui (original) (raw)

It looks like the field is solving an actual problem, because otherwise the delegate is collected.

Apple says it's a weak property: https://developer.apple.com/documentation/uikit/uicontextmenuinteraction/3295925-delegate?language=objc, so unless managed code keeps a reference to it, it'll be collected.

It doesn't look like there should be a leak here though, because the delegate instance doesn't have any references to anything else.

However, there's a race condition, the managed FlyoutUIContextMenuInteractionDelegate instance is created in the call to the base constructor, then fetched in the next line. If the GC runs between those two lines, the delegate can still be collected.

Ideally it would be possible to fix this by making MauiUIContextMenuInteraction implement IUIContextMenuInteractionDelegate and the corresponding interface method:

class MauiUIContextMenuInteraction : UIContextMenuInteraction, IUIContextMenuInteractionDelegate { public MauiUIContextMenuInteraction (IElementHandler handler) : base (this) { /* ... */ }

UIContextMenuConfiguration? IUIContextMenuInteractionDelegate.GetConfigurationForMenu(UIContextMenuInteraction interaction, CGPoint location)
{ /* ... */ }

}

but that runs into:

error CS0027: Keyword 'this' is not available in the current context

But I believe his should fix the race condition and keep the delegate alive:

class MauiUIContextMenuInteraction : UIContextMenuInteraction, IUIContextMenuInteractionDelegate { IUIContextMenuInteractionDelegate? _uiContextMenuInteractionDelegate; public MauiUIContextMenuInteraction (IElementHandler handler) : base (CreateDelegate (out var del) { _uiContextMenuInteractionDelegate = del; }

static IUIContextMenuInteractionDelegate CreateDelegate (out IUIContextMenuInteractionDelegate del)
{
    return del = new FlyoutUIContextMenuInteractionDelegate();
}

}