Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ea83156

Browse files
authored
[iOS] Fix App crash when use WebView with iOS VoiceOver (#52484)
This PR fix the issue [flutter/flutter #140528](flutter/flutter#140528). This fix cleans up declarations regarding `retain` and `release`. `flutterAccessibilityContainer` needs to be managed in `FlutterPlatformViews.mm`, and problems will occur if `retain` or `release` is performed in `SemanticsObject.mm`. This fix is checked by the `testFlutterPlatformViewSemanticsContainer` function in the `SemanticsObjectTest.mm`. The result is not changed. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent 6841af7 commit ea83156

File tree

4 files changed

+24
-17
lines changed

4 files changed

+24
-17
lines changed

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -981,10 +981,6 @@ @implementation FlutterTouchInterceptingView {
981981
fml::scoped_nsobject<DelayingGestureRecognizer> _delayingRecognizer;
982982
FlutterPlatformViewGestureRecognizersBlockingPolicy _blockingPolicy;
983983
UIView* _embeddedView;
984-
// The used as the accessiblityContainer.
985-
// The `accessiblityContainer` is used in UIKit to determine the parent of this accessibility
986-
// node.
987-
NSObject* _flutterAccessibilityContainer;
988984
}
989985
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView
990986
platformViewsController:
@@ -1063,14 +1059,15 @@ - (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
10631059
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
10641060
}
10651061

1066-
- (void)setFlutterAccessibilityContainer:(NSObject*)flutterAccessibilityContainer {
1067-
_flutterAccessibilityContainer = flutterAccessibilityContainer;
1068-
}
1069-
10701062
- (id)accessibilityContainer {
10711063
return _flutterAccessibilityContainer;
10721064
}
10731065

1066+
- (void)dealloc {
1067+
[_flutterAccessibilityContainer release];
1068+
[super dealloc];
1069+
}
1070+
10741071
@end
10751072

10761073
@implementation DelayingGestureRecognizer {

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ class FlutterPlatformViewsController {
440440
- (UIView*)embeddedView;
441441

442442
// Sets flutterAccessibilityContainer as this view's accessibilityContainer.
443-
- (void)setFlutterAccessibilityContainer:(NSObject*)flutterAccessibilityContainer;
443+
@property(nonatomic, retain) id flutterAccessibilityContainer;
444444
@end
445445

446446
@interface UIView (FirstResponder)

shell/platform/darwin/ios/framework/Source/SemanticsObject.mm

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ - (UIAccessibilityTraits)accessibilityTraits {
867867
@end
868868

869869
@interface FlutterPlatformViewSemanticsContainer ()
870-
@property(nonatomic, retain) UIView* platformView;
870+
@property(nonatomic, assign) UIView* platformView;
871871
@end
872872

873873
@implementation FlutterPlatformViewSemanticsContainer
@@ -876,14 +876,13 @@ - (instancetype)initWithBridge:(fml::WeakPtr<flutter::AccessibilityBridgeIos>)br
876876
uid:(int32_t)uid
877877
platformView:(nonnull FlutterTouchInterceptingView*)platformView {
878878
if (self = [super initWithBridge:bridge uid:uid]) {
879-
_platformView = [platformView retain];
879+
_platformView = platformView;
880880
[platformView setFlutterAccessibilityContainer:self];
881881
}
882882
return self;
883883
}
884884

885885
- (void)dealloc {
886-
[_platformView release];
887886
_platformView = nil;
888887
[super dealloc];
889888
}

shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -994,19 +994,30 @@ - (void)testFlutterPlatformViewSemanticsContainer {
994994
new flutter::testing::MockAccessibilityBridge());
995995
fml::WeakPtr<flutter::testing::MockAccessibilityBridge> bridge = factory.GetWeakPtr();
996996
__weak FlutterTouchInterceptingView* weakPlatformView;
997+
__weak FlutterPlatformViewSemanticsContainer* weakContainer;
997998
@autoreleasepool {
998999
FlutterTouchInterceptingView* platformView = [[FlutterTouchInterceptingView alloc] init];
9991000
weakPlatformView = platformView;
1000-
FlutterPlatformViewSemanticsContainer* container =
1001-
[[FlutterPlatformViewSemanticsContainer alloc] initWithBridge:bridge
1002-
uid:1
1003-
platformView:platformView];
1004-
XCTAssertEqualObjects(platformView.accessibilityContainer, container);
1001+
1002+
@autoreleasepool {
1003+
FlutterPlatformViewSemanticsContainer* container =
1004+
[[FlutterPlatformViewSemanticsContainer alloc] initWithBridge:bridge
1005+
uid:1
1006+
platformView:platformView];
1007+
weakContainer = container;
1008+
XCTAssertEqualObjects(platformView.accessibilityContainer, container);
1009+
XCTAssertNotNil(weakPlatformView);
1010+
XCTAssertNotNil(weakContainer);
1011+
}
1012+
// Check the variables are still lived.
1013+
// `container` is `retain` in `platformView`, so it will not be nil here.
10051014
XCTAssertNotNil(weakPlatformView);
1015+
XCTAssertNotNil(weakContainer);
10061016
}
10071017
// Check if there's no more strong references to `platformView` after container and platformView
10081018
// are released.
10091019
XCTAssertNil(weakPlatformView);
1020+
XCTAssertNil(weakContainer);
10101021
}
10111022

10121023
- (void)testTextInputSemanticsObject {

0 commit comments

Comments
 (0)