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

Commit f553caa

Browse files
authored
Migrate FlutterView, FlutterPlatformViews, FlutterOverlayView to ARC (#52535)
Smart pointers support ARC as of #47612, and the unit tests were migrated in #48162. Migrate `FlutterView`, `FlutterPlatformViews`, and `FlutterOverlayView` from MRC to ARC. Part of flutter/flutter#137801.
1 parent 254927e commit f553caa

File tree

8 files changed

+115
-123
lines changed

8 files changed

+115
-123
lines changed

shell/platform/darwin/ios/BUILD.gn

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ source_set("flutter_framework_source_arc") {
7373
"framework/Source/FlutterKeyboardManager.mm",
7474
"framework/Source/FlutterMetalLayer.h",
7575
"framework/Source/FlutterMetalLayer.mm",
76+
"framework/Source/FlutterOverlayView.h",
77+
"framework/Source/FlutterOverlayView.mm",
78+
"framework/Source/FlutterPlatformViews.mm",
79+
"framework/Source/FlutterPlatformViews_Internal.h",
80+
"framework/Source/FlutterPlatformViews_Internal.mm",
7681
"framework/Source/FlutterRestorationPlugin.h",
7782
"framework/Source/FlutterRestorationPlugin.mm",
7883
"framework/Source/FlutterSpellCheckPlugin.h",
@@ -87,6 +92,9 @@ source_set("flutter_framework_source_arc") {
8792
"framework/Source/FlutterUndoManagerDelegate.h",
8893
"framework/Source/FlutterUndoManagerPlugin.h",
8994
"framework/Source/FlutterUndoManagerPlugin.mm",
95+
"framework/Source/FlutterView.h",
96+
"framework/Source/FlutterView.mm",
97+
"framework/Source/FlutterViewResponder.h",
9098
"framework/Source/KeyCodeMap.g.mm",
9199
"framework/Source/KeyCodeMap_Internal.h",
92100
"framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h",
@@ -160,18 +168,11 @@ source_set("flutter_framework_source") {
160168
"framework/Source/FlutterEngineGroup.mm",
161169
"framework/Source/FlutterEngine_Internal.h",
162170
"framework/Source/FlutterHeadlessDartRunner.mm",
163-
"framework/Source/FlutterOverlayView.h",
164-
"framework/Source/FlutterOverlayView.mm",
165171
"framework/Source/FlutterPlatformPlugin.h",
166172
"framework/Source/FlutterPlatformPlugin.mm",
167-
"framework/Source/FlutterPlatformViews.mm",
168-
"framework/Source/FlutterPlatformViews_Internal.h",
169-
"framework/Source/FlutterPlatformViews_Internal.mm",
170173
"framework/Source/FlutterPluginAppLifeCycleDelegate.mm",
171174
"framework/Source/FlutterSemanticsScrollView.h",
172175
"framework/Source/FlutterSemanticsScrollView.mm",
173-
"framework/Source/FlutterView.h",
174-
"framework/Source/FlutterView.mm",
175176
"framework/Source/FlutterViewController.mm",
176177
"framework/Source/FlutterViewController_Internal.h",
177178
"framework/Source/SemanticsObject.h",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
1010
#include "fml/platform/darwin/cf_utils.h"
1111

12+
FLUTTER_ASSERT_ARC
13+
1214
// This is mostly a duplication of FlutterView.
1315
// TODO(amirh): once GL support is in evaluate if we can merge this with FlutterView.
1416
@implementation FlutterOverlayView {

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

Lines changed: 50 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
1212
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
1313

14+
FLUTTER_ASSERT_ARC
15+
1416
@implementation UIView (FirstResponder)
1517
- (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
1618
if (self.isFirstResponder) {
@@ -91,7 +93,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
9193
overlay_view.reset([[FlutterOverlayView alloc] init]);
9294
overlay_view_wrapper.reset([[FlutterOverlayView alloc] init]);
9395

94-
auto ca_layer = fml::scoped_nsobject<CALayer>{[[overlay_view.get() layer] retain]};
96+
auto ca_layer = fml::scoped_nsobject<CALayer>{[overlay_view.get() layer]};
9597
std::unique_ptr<IOSSurface> ios_surface = IOSSurface::Create(ios_context, ca_layer);
9698
std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface();
9799

@@ -105,7 +107,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
105107
overlay_view_wrapper.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale
106108
pixelFormat:pixel_format]);
107109

108-
auto ca_layer = fml::scoped_nsobject<CALayer>{[[overlay_view.get() layer] retain]};
110+
auto ca_layer = fml::scoped_nsobject<CALayer>{[overlay_view.get() layer]};
109111
std::unique_ptr<IOSSurface> ios_surface = IOSSurface::Create(ios_context, ca_layer);
110112
std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface(gr_context);
111113

@@ -159,12 +161,12 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
159161
}
160162

161163
void FlutterPlatformViewsController::SetFlutterView(UIView* flutter_view) {
162-
flutter_view_.reset([flutter_view retain]);
164+
flutter_view_.reset(flutter_view);
163165
}
164166

165167
void FlutterPlatformViewsController::SetFlutterViewController(
166168
UIViewController<FlutterViewResponder>* flutter_view_controller) {
167-
flutter_view_controller_.reset([flutter_view_controller retain]);
169+
flutter_view_controller_.reset(flutter_view_controller);
168170
}
169171

170172
UIViewController<FlutterViewResponder>* FlutterPlatformViewsController::getFlutterViewController() {
@@ -231,21 +233,19 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
231233
// Set a unique view identifier, so the platform view can be identified in unit tests.
232234
platform_view.accessibilityIdentifier =
233235
[NSString stringWithFormat:@"platform_view[%lld]", viewId];
234-
views_[viewId] = fml::scoped_nsobject<NSObject<FlutterPlatformView>>([embedded_view retain]);
236+
views_[viewId] = fml::scoped_nsobject<NSObject<FlutterPlatformView>>(embedded_view);
235237

236-
FlutterTouchInterceptingView* touch_interceptor = [[[FlutterTouchInterceptingView alloc]
238+
FlutterTouchInterceptingView* touch_interceptor = [[FlutterTouchInterceptingView alloc]
237239
initWithEmbeddedView:platform_view
238240
platformViewsController:GetWeakPtr()
239-
gestureRecognizersBlockingPolicy:gesture_recognizers_blocking_policies_[viewType]]
240-
autorelease];
241+
gestureRecognizersBlockingPolicy:gesture_recognizers_blocking_policies_[viewType]];
241242

242243
touch_interceptors_[viewId] =
243-
fml::scoped_nsobject<FlutterTouchInterceptingView>([touch_interceptor retain]);
244+
fml::scoped_nsobject<FlutterTouchInterceptingView>(touch_interceptor);
244245

245-
ChildClippingView* clipping_view =
246-
[[[ChildClippingView alloc] initWithFrame:CGRectZero] autorelease];
246+
ChildClippingView* clipping_view = [[ChildClippingView alloc] initWithFrame:CGRectZero];
247247
[clipping_view addSubview:touch_interceptor];
248-
root_views_[viewId] = fml::scoped_nsobject<UIView>([clipping_view retain]);
248+
root_views_[viewId] = fml::scoped_nsobject<UIView>(clipping_view);
249249

250250
result(nil);
251251
}
@@ -307,8 +307,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
307307
FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy) {
308308
std::string idString([factoryId UTF8String]);
309309
FML_CHECK(factories_.count(idString) == 0);
310-
factories_[idString] =
311-
fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>([factory retain]);
310+
factories_[idString] = fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>(factory);
312311
gesture_recognizers_blocking_policies_[idString] = gestureRecognizerBlockingPolicy;
313312
}
314313

@@ -417,7 +416,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
417416

418417
long FlutterPlatformViewsController::FindFirstResponderPlatformViewId() {
419418
for (auto const& [id, root_view] : root_views_) {
420-
if ((UIView*)(root_view.get()).flt_hasFirstResponderInViewHierarchySubtree) {
419+
if (((UIView*)root_view.get()).flt_hasFirstResponderInViewHierarchySubtree) {
421420
return id;
422421
}
423422
}
@@ -460,7 +459,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
460459
ChildClippingView* clipView = (ChildClippingView*)embedded_view.superview;
461460

462461
SkMatrix transformMatrix;
463-
NSMutableArray* blurFilters = [[[NSMutableArray alloc] init] autorelease];
462+
NSMutableArray* blurFilters = [[NSMutableArray alloc] init];
464463
FML_DCHECK(!clipView.maskView ||
465464
[clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]);
466465
if (clipView.maskView) {
@@ -530,12 +529,11 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
530529
// is not supported in Quartz's gaussianBlur CAFilter, so it is not used
531530
// to blur the PlatformView.
532531
CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x();
533-
UIVisualEffectView* visualEffectView = [[[UIVisualEffectView alloc]
534-
initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]] autorelease];
535-
PlatformViewFilter* filter =
536-
[[[PlatformViewFilter alloc] initWithFrame:frameInClipView
537-
blurRadius:blurRadius
538-
visualEffectView:visualEffectView] autorelease];
532+
UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
533+
initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
534+
PlatformViewFilter* filter = [[PlatformViewFilter alloc] initWithFrame:frameInClipView
535+
blurRadius:blurRadius
536+
visualEffectView:visualEffectView];
539537
if (!filter) {
540538
canApplyBlurBackdrop = NO;
541539
} else {
@@ -950,11 +948,13 @@ @interface DelayingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerD
950948

951949
// Indicates that if the `DelayingGestureRecognizer`'s state should be set to
952950
// `UIGestureRecognizerStateEnded` during next `touchesEnded` call.
953-
@property(nonatomic) bool shouldEndInNextTouchesEnded;
951+
@property(nonatomic) BOOL shouldEndInNextTouchesEnded;
954952

955953
// Indicates that the `DelayingGestureRecognizer`'s `touchesEnded` has been invoked without
956954
// setting the state to `UIGestureRecognizerStateEnded`.
957-
@property(nonatomic) bool touchedEndedWithoutBlocking;
955+
@property(nonatomic) BOOL touchedEndedWithoutBlocking;
956+
957+
@property(nonatomic, readonly) UIGestureRecognizer* forwardingRecognizer;
958958

959959
- (instancetype)initWithTarget:(id)target
960960
action:(SEL)action
@@ -977,11 +977,13 @@ - (instancetype)initWithTarget:(id)target
977977
(fml::WeakPtr<flutter::FlutterPlatformViewsController>)platformViewsController;
978978
@end
979979

980-
@implementation FlutterTouchInterceptingView {
981-
fml::scoped_nsobject<DelayingGestureRecognizer> _delayingRecognizer;
982-
FlutterPlatformViewGestureRecognizersBlockingPolicy _blockingPolicy;
983-
UIView* _embeddedView;
984-
}
980+
@interface FlutterTouchInterceptingView ()
981+
@property(nonatomic, weak, readonly) UIView* embeddedView;
982+
@property(nonatomic, readonly) DelayingGestureRecognizer* delayingRecognizer;
983+
@property(nonatomic, readonly) FlutterPlatformViewGestureRecognizersBlockingPolicy blockingPolicy;
984+
@end
985+
986+
@implementation FlutterTouchInterceptingView
985987
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView
986988
platformViewsController:
987989
(fml::WeakPtr<flutter::FlutterPlatformViewsController>)platformViewsController
@@ -996,47 +998,42 @@ - (instancetype)initWithEmbeddedView:(UIView*)embeddedView
996998

997999
[self addSubview:embeddedView];
9981000

999-
ForwardingGestureRecognizer* forwardingRecognizer = [[[ForwardingGestureRecognizer alloc]
1000-
initWithTarget:self
1001-
platformViewsController:std::move(platformViewsController)] autorelease];
1001+
ForwardingGestureRecognizer* forwardingRecognizer =
1002+
[[ForwardingGestureRecognizer alloc] initWithTarget:self
1003+
platformViewsController:platformViewsController];
10021004

1003-
_delayingRecognizer.reset([[DelayingGestureRecognizer alloc]
1004-
initWithTarget:self
1005-
action:nil
1006-
forwardingRecognizer:forwardingRecognizer]);
1005+
_delayingRecognizer = [[DelayingGestureRecognizer alloc] initWithTarget:self
1006+
action:nil
1007+
forwardingRecognizer:forwardingRecognizer];
10071008
_blockingPolicy = blockingPolicy;
10081009

1009-
[self addGestureRecognizer:_delayingRecognizer.get()];
1010+
[self addGestureRecognizer:_delayingRecognizer];
10101011
[self addGestureRecognizer:forwardingRecognizer];
10111012
}
10121013
return self;
10131014
}
10141015

1015-
- (UIView*)embeddedView {
1016-
return [[_embeddedView retain] autorelease];
1017-
}
1018-
10191016
- (void)releaseGesture {
1020-
_delayingRecognizer.get().state = UIGestureRecognizerStateFailed;
1017+
self.delayingRecognizer.state = UIGestureRecognizerStateFailed;
10211018
}
10221019

10231020
- (void)blockGesture {
10241021
switch (_blockingPolicy) {
10251022
case FlutterPlatformViewGestureRecognizersBlockingPolicyEager:
10261023
// We block all other gesture recognizers immediately in this policy.
1027-
_delayingRecognizer.get().state = UIGestureRecognizerStateEnded;
1024+
self.delayingRecognizer.state = UIGestureRecognizerStateEnded;
10281025
break;
10291026
case FlutterPlatformViewGestureRecognizersBlockingPolicyWaitUntilTouchesEnded:
1030-
if (_delayingRecognizer.get().touchedEndedWithoutBlocking) {
1027+
if (self.delayingRecognizer.touchedEndedWithoutBlocking) {
10311028
// If touchesEnded of the `DelayingGesureRecognizer` has been already invoked,
10321029
// we want to set the state of the `DelayingGesureRecognizer` to
10331030
// `UIGestureRecognizerStateEnded` as soon as possible.
1034-
_delayingRecognizer.get().state = UIGestureRecognizerStateEnded;
1031+
self.delayingRecognizer.state = UIGestureRecognizerStateEnded;
10351032
} else {
10361033
// If touchesEnded of the `DelayingGesureRecognizer` has not been invoked,
10371034
// We will set a flag to notify the `DelayingGesureRecognizer` to set the state to
10381035
// `UIGestureRecognizerStateEnded` when touchesEnded is called.
1039-
_delayingRecognizer.get().shouldEndInNextTouchesEnded = YES;
1036+
self.delayingRecognizer.shouldEndInNextTouchesEnded = YES;
10401037
}
10411038
break;
10421039
default:
@@ -1060,19 +1057,12 @@ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
10601057
}
10611058

10621059
- (id)accessibilityContainer {
1063-
return _flutterAccessibilityContainer;
1064-
}
1065-
1066-
- (void)dealloc {
1067-
[_flutterAccessibilityContainer release];
1068-
[super dealloc];
1060+
return self.flutterAccessibilityContainer;
10691061
}
10701062

10711063
@end
10721064

1073-
@implementation DelayingGestureRecognizer {
1074-
fml::scoped_nsobject<UIGestureRecognizer> _forwardingRecognizer;
1075-
}
1065+
@implementation DelayingGestureRecognizer
10761066

10771067
- (instancetype)initWithTarget:(id)target
10781068
action:(SEL)action
@@ -1082,9 +1072,9 @@ - (instancetype)initWithTarget:(id)target
10821072
self.delaysTouchesBegan = YES;
10831073
self.delaysTouchesEnded = YES;
10841074
self.delegate = self;
1085-
self.shouldEndInNextTouchesEnded = NO;
1086-
self.touchedEndedWithoutBlocking = NO;
1087-
_forwardingRecognizer.reset([forwardingRecognizer retain]);
1075+
_shouldEndInNextTouchesEnded = NO;
1076+
_touchedEndedWithoutBlocking = NO;
1077+
_forwardingRecognizer = forwardingRecognizer;
10881078
}
10891079
return self;
10901080
}
@@ -1093,7 +1083,7 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
10931083
shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {
10941084
// The forwarding gesture recognizer should always get all touch events, so it should not be
10951085
// required to fail by any other gesture recognizer.
1096-
return otherGestureRecognizer != _forwardingRecognizer.get() && otherGestureRecognizer != self;
1086+
return otherGestureRecognizer != _forwardingRecognizer && otherGestureRecognizer != self;
10971087
}
10981088

10991089
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
@@ -1158,7 +1148,7 @@ - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
11581148
// At the start of each gesture sequence, we reset the `_flutterViewController`,
11591149
// so that all the touch events in the same sequence are forwarded to the same
11601150
// `_flutterViewController`.
1161-
_flutterViewController.reset([_platformViewsController->getFlutterViewController() retain]);
1151+
_flutterViewController.reset(_platformViewsController->getFlutterViewController());
11621152
}
11631153
[_flutterViewController.get() touchesBegan:touches withEvent:event];
11641154
_currentTouchPointersCount += touches.count;

0 commit comments

Comments
 (0)