From 4833535dccc8e45a9940416091e93db462273aea Mon Sep 17 00:00:00 2001 From: KyleWong Date: Fri, 11 Oct 2019 00:14:18 +0800 Subject: [PATCH] Fix an objc_overrelease_during_dealloc_error. --- shell/platform/darwin/ios/platform_view_ios.h | 3 +- .../platform/darwin/ios/platform_view_ios.mm | 35 +++++++++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index b93379d89a83d..89efebae77cbc 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -46,6 +46,8 @@ class PlatformViewIOS final : public PlatformView { // |PlatformView| void SetSemanticsEnabled(bool enabled) override; + + void OnFlutterViewControllerDealloced(); private: fml::WeakPtr owner_controller_; @@ -58,7 +60,6 @@ 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_; // |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 af8bbfec1c570..1495731f61dfa 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -19,6 +19,10 @@ namespace flutter { +static void notificationHandler(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { + (static_cast(observer))->OnFlutterViewControllerDealloced(); +} + PlatformViewIOS::PlatformViewIOS(PlatformView::Delegate& delegate, flutter::TaskRunners task_runners) : PlatformView(delegate, std::move(task_runners)) { @@ -27,7 +31,13 @@ #endif // !TARGET_IPHONE_SIMULATOR } -PlatformViewIOS::~PlatformViewIOS() = default; +PlatformViewIOS::~PlatformViewIOS() { + CFNotificationCenterRemoveEveryObserver + ( + CFNotificationCenterGetLocalCenter(), + this + ); +}; PlatformMessageRouter& PlatformViewIOS::GetPlatformMessageRouter() { return platform_message_router_; @@ -54,15 +64,15 @@ // 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(); - }]); + CFNotificationCenterAddObserver + ( + CFNotificationCenterGetLocalCenter(), + this, + ¬ificationHandler, + (__bridge CFStringRef)FlutterViewControllerWillDealloc, + owner_controller_.get(), + CFNotificationSuspensionBehaviorDeliverImmediately + ); if (owner_controller_) { ios_surface_ = @@ -81,6 +91,11 @@ new AccessibilityBridge(static_cast(owner_controller_.get().view), } } +void PlatformViewIOS::OnFlutterViewControllerDealloced() { + accessibility_bridge_.reset(); + owner_controller_.reset(); +} + PointerDataDispatcherMaker PlatformViewIOS::GetDispatcherMaker() { return [](DefaultPointerDataDispatcher::Delegate& delegate) { return std::make_unique(delegate);