From a1f254977be77bb558705bc93b63897fbf7f13f8 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 9 Feb 2021 13:31:01 -0800 Subject: [PATCH] Fix FlutterPlatformViewSemanticsContainer retain cycle with SemanticsObject (flutter/engine#24308) --- .../ios/framework/Source/SemanticsObject.mm | 29 +++++++++++++++++-- .../framework/Source/SemanticsObjectTest.mm | 12 ++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm index ddebb029c99..134b75e40b0 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm @@ -576,10 +576,35 @@ flutter::SemanticsAction GetSemanticsActionForScrollDirection( [super dealloc]; } -- (NSArray*)accessibilityElements { - return @[ _semanticsObject, _platformView ]; +#pragma mark - UIAccessibilityContainer overrides + +- (NSInteger)accessibilityElementCount { + // This container should only contain 2 elements: + // 1. The semantic object that represents this container. + // 2. The platform view object. + return 2; } +- (nullable id)accessibilityElementAtIndex:(NSInteger)index { + FML_DCHECK(index < 2); + if (index == 0) { + return _semanticsObject; + } else { + return _platformView; + } +} + +- (NSInteger)indexOfAccessibilityElement:(id)element { + FML_DCHECK(element == _semanticsObject || element == _platformView); + if (element == _semanticsObject) { + return 0; + } else { + return 1; + } +} + +#pragma mark - UIAccessibilityElement overrides + - (CGRect)accessibilityFrame { return _semanticsObject.accessibilityFrame; } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm index b03144a5f3a..7a79ad596f6 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm @@ -217,4 +217,16 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos { XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen); } +- (void)testSemanticsObjectAndPlatformViewSemanticsContainerDontHaveRetainCycle { + fml::WeakPtrFactory factory( + new flutter::MockAccessibilityBridge()); + fml::WeakPtr bridge = factory.GetWeakPtr(); + SemanticsObject* object = [[SemanticsObject alloc] initWithBridge:bridge uid:1]; + object.platformViewSemanticsContainer = + [[FlutterPlatformViewSemanticsContainer alloc] initWithSemanticsObject:object]; + __weak SemanticsObject* weakObject = object; + object = nil; + XCTAssertNil(weakObject); +} + @end