-
Notifications
You must be signed in to change notification settings - Fork 30.2k
[iOS] FlutterViewController Memory Leak #163841
Description
Steps to reproduce
I am adding flutter screens to an existing iOS app using the add-to-app process.
I am using a subclass of FlutterViewController, and have found that it doesn't get collected by ARC after the view controller is popped off the navigation stack, as expected.
This behaviour is also present in the multiple flutters add-to-app sample code here.
Steps to reproduce:
- Build and run the "multiple flutters iOS" project as described at the link above.
- Tap the "Next" button to push an instance of
SingleFlutterViewControlleronto the navigation stack. - Press the back button to pop the
SingleFlutterViewControlleroff the navigation stack. - Use the "Debug Memory Graph" feature on Xcode, and search for
SingleFlutterViewController.
Expected result:
The SingleFlutterViewController has been collected by ARC and is not present in the memory graph.
Actual result:
The SingleFlutterViewController is present in the memory graph, even after it has been removed from the navigation controller.
Also note that pushing and popping multiple instances of SingleFlutterViewController will result in multiple instances being kept in the memory graph.
See attached screenshot of the Xcode memory graph.
Experimentally, I found that calling destroyContext() on the FlutterViewControllers engine instance will cause the FlutterViewController to be collected.
So reworking the sample code as below fixes the issue, however I don't think I should have to manually call destroyContext.
class SingleFlutterViewController: UIViewController, DataModelObserver {
private var channel: FlutterMethodChannel?
private let flutterViewController: FlutterViewController
init(withEntrypoint entryPoint: String?) {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let newEngine = appDelegate.engines.makeEngine(withEntrypoint: entryPoint, libraryURI: nil)
GeneratedPluginRegistrant.register(with: newEngine)
flutterViewController = FlutterViewController(engine: newEngine, nibName: nil, bundle: nil)
super.init(nibName: nil, bundle: nil)
DataModel.shared.addObserver(observer: self)
}
deinit {
DataModel.shared.removeObserver(observer: self)
flutterViewController.engine.destroyContext()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func onCountUpdate(newCount: Int64) {
if let channel = channel {
channel.invokeMethod("setCount", arguments: newCount)
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(flutterViewController.view)
flutterViewController.view.frame = view.bounds
addChild(flutterViewController)
flutterViewController.didMove(toParent: self)
channel = FlutterMethodChannel(
name: "multiple-flutters", binaryMessenger: flutterViewController.engine.binaryMessenger)
channel!.invokeMethod("setCount", arguments: DataModel.shared.count)
let navController = self.navigationController!
channel!.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
if call.method == "incrementCount" {
DataModel.shared.count = DataModel.shared.count + 1
result(nil)
} else if call.method == "next" {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "NativeViewCount")
navController.pushViewController(vc, animated: true)
result(nil)
} else {
result(FlutterMethodNotImplemented)
}
}
}
}Code sample
Code sample
As described above, see the add to app multiple flutters example.
What target platforms are you seeing this bug on?
iOS
OS/Browser name and version | Device information
I'm building using Xcode 16.2 and Mac OS 15.3.1.
I'm using Flutter 3.29.0.
I am running on an iPhone 16 Pro simulator, using iOS 18.3
Does the problem occur on emulator/simulator as well as on physical devices?
Unknown
Logs
Logs
[Paste your logs here]Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.29.0, on macOS 15.3.1 24D70 darwin-arm64 (Rosetta), locale en-GB) [895ms]
• Flutter version 3.29.0 on channel stable at /Users/jackcostigan/development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 35c388afb5 (11 days ago), 2025-02-10 12:48:41 -0800
• Engine revision f73bfc4522
• Dart version 3.7.0
• DevTools version 2.42.2
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [933ms]
• Android SDK at /Users/jackcostigan/Library/Android/sdk
✗ cmdline-tools component is missing
Run `path/to/sdkmanager --install "cmdline-tools;latest"`
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/to/macos-android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [1,694ms]
• Xcode at /Applications/Xcode-16.2.0.app/Contents/Developer
• Build 16C5032a
• CocoaPods version 1.16.2
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google
Chrome) [47ms]
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Android Studio (version 2023.1) [46ms]
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
[✓] VS Code (version 1.90.0) [42ms]
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (3 available) [7.4s]
• iPhone 16 Pro (mobile) • C292E601-ED3D-4EFD-BC77-517D624BD6C7 • ios • com.apple.CoreSimulator.SimRuntime.iOS-18-3
(simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 15.3.1 24D70 darwin-arm64 (Rosetta)
• Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin • macOS 15.3.1 24D70 darwin-arm64 (Rosetta)
[✓] Network resources [913ms]
• All expected network resources are available.
! Doctor found issues in 2 categories.