iOS: Clean up @synthesize directives / ivars (flutter/engine#56665)

In modern Objective-C, `@property` directives automatically generate a backing ivar (property name prefixed with an underscore), the getter, and (for readwrite properties) the setter. `@synthesize` directives are generally only required if the backing ivar has a different name from the property.

Also updates the FlutterMetalLayer API to match CAMetalLayer:
* Adds API_AVAILABLE declaration to match that on CAMetalLayer.
* Eliminates wantsExtendedDynamicRangeContent property as it's also part of CALayer's interface and unused in our implementation.

Also eliminates unnecessary ivars where they're being synthesized by `@property` declarations.

Previously, we were overriding the behaviour of
UIViewController.prefersStatusBarHidden by synthesizing _flutterPrefersStatusBarHidden as a backing ivar. Since we're explicitly overriding the behaviour of a superclass, it's more idiomatic to synthesize a private property or explicitly declare an ivar then explicitly override the getter instead.

Further, this adds documentation to cases where `@synthesize` directives are required, such as:
* Creating a backing ivar for a readonly property.
* Creating a backing ivar for a property with a custom getter/setter.
* Synthesising the ivar, getter, and setter for a property declared in a protocol being implemented.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Chris Bracken 2024-11-17 16:29:24 -08:00 committed by GitHub
parent 7be64cf1be
commit ab0a04d3a7
12 changed files with 36 additions and 32 deletions

View File

@ -9,16 +9,20 @@
/// Drop-in replacement (as far as Flutter is concerned) for CAMetalLayer
/// that can present with transaction from a background thread.
///
/// Properties and method declarations must exactly match those in the
/// CAMetalLayer interface declaration.
@interface FlutterMetalLayer : CALayer
@property(nullable, retain) id<MTLDevice> device;
@property(nullable, readonly) id<MTLDevice> preferredDevice;
@property(nullable, readonly)
id<MTLDevice> preferredDevice API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0))
API_UNAVAILABLE(watchos);
@property MTLPixelFormat pixelFormat;
@property BOOL framebufferOnly;
@property CGSize drawableSize;
@property BOOL presentsWithTransaction;
@property(nullable) CGColorSpaceRef colorspace;
@property BOOL wantsExtendedDynamicRangeContent;
- (nullable id<CAMetalDrawable>)nextDrawable;

View File

@ -57,11 +57,7 @@ extern CFTimeInterval display_link_target;
@end
@interface FlutterTexture : NSObject {
id<MTLTexture> _texture;
IOSurface* _surface;
CFTimeInterval _presentedTime;
}
@interface FlutterTexture : NSObject
@property(readonly, nonatomic) id<MTLTexture> texture;
@property(readonly, nonatomic) IOSurface* surface;
@ -72,11 +68,6 @@ extern CFTimeInterval display_link_target;
@implementation FlutterTexture
@synthesize texture = _texture;
@synthesize surface = _surface;
@synthesize presentedTime = _presentedTime;
@synthesize waitingForCompletion;
- (instancetype)initWithTexture:(id<MTLTexture>)texture surface:(IOSurface*)surface {
if (self = [super init]) {
_texture = texture;
@ -187,13 +178,6 @@ extern CFTimeInterval display_link_target;
@implementation FlutterMetalLayer
@synthesize preferredDevice = _preferredDevice;
@synthesize device = _device;
@synthesize pixelFormat = _pixelFormat;
@synthesize framebufferOnly = _framebufferOnly;
@synthesize colorspace = _colorspace;
@synthesize wantsExtendedDynamicRangeContent = _wantsExtendedDynamicRangeContent;
- (instancetype)init {
if (self = [super init]) {
_preferredDevice = MTLCreateSystemDefaultDevice();

View File

@ -662,6 +662,7 @@ static BOOL IsSelectionRectBoundaryCloserToPoint(CGPoint point,
@implementation FlutterTextSelectionRect
// Synthesize properties declared readonly in UITextSelectionRect.
@synthesize rect = _rect;
@synthesize writingDirection = _writingDirection;
@synthesize containsStart = _containsStart;

View File

@ -79,6 +79,9 @@ typedef struct MouseState {
@property(nonatomic, assign) BOOL isHomeIndicatorHidden;
@property(nonatomic, assign) BOOL isPresentingViewControllerAnimating;
// Internal state backing override of UIView.prefersStatusBarHidden.
@property(nonatomic, assign) BOOL flutterPrefersStatusBarHidden;
@property(nonatomic, strong) NSMutableSet<NSNumber*>* ongoingTouches;
// This scroll view is a workaround to accommodate iOS 13 and higher. There isn't a way to get
// touches on the status bar to trigger scrolling to the top of a scroll view. We place a
@ -157,9 +160,13 @@ typedef struct MouseState {
MouseState _mouseState;
}
// Synthesize properties with an overridden getter/setter.
@synthesize viewOpaque = _viewOpaque;
@synthesize displayingFlutterUI = _displayingFlutterUI;
@synthesize prefersStatusBarHidden = _flutterPrefersStatusBarHidden;
// TODO(dkwingsmt): https://github.com/flutter/flutter/issues/138168
// No backing ivar is currently required; when multiple views are supported, we'll need to
// synthesize the ivar and store the view identifier.
@dynamic viewIdentifier;
#pragma mark - Manage and override all designated initializers
@ -2302,14 +2309,14 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
}
- (void)setPrefersStatusBarHidden:(BOOL)hidden {
if (hidden != _flutterPrefersStatusBarHidden) {
_flutterPrefersStatusBarHidden = hidden;
if (hidden != self.flutterPrefersStatusBarHidden) {
self.flutterPrefersStatusBarHidden = hidden;
[self setNeedsStatusBarAppearanceUpdate];
}
}
- (BOOL)prefersStatusBarHidden {
return _flutterPrefersStatusBarHidden;
return self.flutterPrefersStatusBarHidden;
}
#pragma mark - Platform views

View File

@ -38,21 +38,26 @@ using namespace flutter::testing;
/// Sometimes we have to use a custom mock to avoid retain cycles in OCMock.
/// Used for testing low memory notification.
@interface FlutterEnginePartialMock : FlutterEngine
@property(nonatomic, strong) FlutterBasicMessageChannel* lifecycleChannel;
@property(nonatomic, strong) FlutterBasicMessageChannel* keyEventChannel;
@property(nonatomic, weak) FlutterViewController* viewController;
@property(nonatomic, strong) FlutterTextInputPlugin* textInputPlugin;
@property(nonatomic, assign) BOOL didCallNotifyLowMemory;
- (FlutterTextInputPlugin*)textInputPlugin;
- (void)sendKeyEvent:(const FlutterKeyEvent&)event
callback:(nullable FlutterKeyEventCallback)callback
userData:(nullable void*)userData;
@end
@implementation FlutterEnginePartialMock
@synthesize viewController;
// Synthesize properties declared readonly in FlutterEngine.
@synthesize lifecycleChannel;
@synthesize keyEventChannel;
@synthesize viewController;
@synthesize textInputPlugin;
- (void)notifyLowMemory {

View File

@ -22,6 +22,7 @@ static const UIAccessibilityTraits kUIAccessibilityTraitUndocumentedEmptyLine =
@implementation FlutterInactiveTextInput
// Synthesize properties declared in UITextInput protocol.
@synthesize beginningOfDocument = _beginningOfDocument;
@synthesize endOfDocument = _endOfDocument;
@synthesize inputDelegate = _inputDelegate;

View File

@ -29,6 +29,7 @@
@implementation FlutterChannelKeyResponder
// Synthesize properties declared in FlutterKeyPrimaryResponder protocol.
@synthesize layoutMap;
- (nonnull instancetype)initWithChannel:(nonnull FlutterBasicMessageChannel*)channel {

View File

@ -473,6 +473,7 @@ struct FlutterKeyPendingResponse {
@implementation FlutterEmbedderKeyResponder
// Synthesize properties declared in FlutterKeyPrimaryResponder protocol.
@synthesize layoutMap;
- (nonnull instancetype)initWithSendEvent:(FlutterSendEmbedderKeyEvent)sendEvent {

View File

@ -25,6 +25,8 @@
@end
@implementation FakePluginRegistrar
// Synthesize properties declared in FlutterPluginRegistrar protocol.
@synthesize messenger;
@synthesize textures;
@synthesize view;

View File

@ -28,8 +28,6 @@
FlutterThreadSynchronizer* _synchronizer;
}
@synthesize synchronizer = _synchronizer;
- (nullable instancetype)init {
self = [super init];
if (self != nil) {

View File

@ -7,8 +7,7 @@
#import "flutter/testing/testing.h"
@interface TestDisplayLink : FlutterDisplayLink {
}
@interface TestDisplayLink : FlutterDisplayLink
@property(nonatomic) CFTimeInterval nominalOutputRefreshPeriod;
@ -16,20 +15,19 @@
@implementation TestDisplayLink
// Synthesize properties declared readonly in FlutterDisplayLink.
@synthesize nominalOutputRefreshPeriod = _nominalOutputRefreshPeriod;
@synthesize delegate = _delegate;
@synthesize paused = _paused;
- (instancetype)init {
if (self = [super init]) {
_paused = YES;
self.paused = YES;
}
return self;
}
- (void)tickWithTimestamp:(CFTimeInterval)timestamp
targetTimestamp:(CFTimeInterval)targetTimestamp {
[_delegate onDisplayLink:timestamp targetTimestamp:targetTimestamp];
[self.delegate onDisplayLink:timestamp targetTimestamp:targetTimestamp];
}
- (void)invalidate {

View File

@ -341,7 +341,9 @@ static void OnKeyboardLayoutChanged(CFNotificationCenterRef center,
FlutterThreadSynchronizer* _threadSynchronizer;
}
// Synthesize properties declared readonly.
@synthesize viewIdentifier = _viewIdentifier;
@dynamic accessibilityBridge;
/**