diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index b93379d89a83d3358a0245cd1ee9cba67a182dc2..5e1e581a3a92b1516a9fb03b190160376caf2a82 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -48,6 +48,20 @@ class PlatformViewIOS final : public PlatformView { void SetSemanticsEnabled(bool enabled) override; private: + /// Smart pointer for use with objective-c observers. + /// This guarentees we remove the observer. + class ScopedObserver { + public: + ScopedObserver(); + ~ScopedObserver(); + void reset(id observer); + ScopedObserver(const ScopedObserver&) = delete; + ScopedObserver& operator=(const ScopedObserver&) = delete; + + private: + id observer_; + }; + fml::WeakPtr owner_controller_; // Since the `ios_surface_` is created on the platform thread but // used on the GPU thread we need to protect it with a mutex. @@ -58,7 +72,7 @@ class PlatformViewIOS final : public PlatformView { std::unique_ptr accessibility_bridge_; fml::scoped_nsprotocol text_input_plugin_; fml::closure firstFrameCallback_; - fml::scoped_nsprotocol dealloc_view_controller_observer_; + ScopedObserver dealloc_view_controller_observer_; // |PlatformView| void HandlePlatformMessage(fml::RefPtr message) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index af8bbfec1c5704579c1fd6644bd205542c729005..bb37fa9610b2b74c34306c6ca2828805c645cf6d 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -54,15 +54,15 @@ void PlatformViewIOS::SetOwnerViewController(fml::WeakPtr // Add an observer that will clear out the owner_controller_ ivar and // the accessibility_bridge_ in case the view controller is deleted. - dealloc_view_controller_observer_.reset([[NSNotificationCenter defaultCenter] - addObserverForName:FlutterViewControllerWillDealloc - object:owner_controller_.get() - queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification* note) { - // Implicit copy of 'this' is fine. - accessibility_bridge_.reset(); - owner_controller_.reset(); - }]); + dealloc_view_controller_observer_.reset( + [[[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc + object:owner_controller_.get() + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification* note) { + // Implicit copy of 'this' is fine. + accessibility_bridge_.reset(); + owner_controller_.reset(); + }] retain]); if (owner_controller_) { ios_surface_ = @@ -174,4 +174,23 @@ void PlatformViewIOS::SetTextInputPlugin(fml::scoped_nsprotocol observer) { + if (observer != observer_) { + if (observer_) { + [[NSNotificationCenter defaultCenter] removeObserver:observer_]; + [observer_ release]; + } + observer_ = observer; + } +} + } // namespace flutter