[webview_flutter_wkwebview] Updates platform views on iOS to only have a weak reference to the native view#11175
[webview_flutter_wkwebview] Updates platform views on iOS to only have a weak reference to the native view#11175bparrishMines wants to merge 7 commits intoflutter:mainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates PlatformViewImpl on iOS to hold a weak reference to its underlying UIView, which is intended to prevent a memory leak. A new test, PlatformViewImplTests.swift, is added to verify this behavior. The implementation of PlatformViewImpl's view() method is changed to handle cases where the underlying UIView may have been deallocated. My review includes one suggestion to make this handling more robust by failing explicitly in what should be an unreachable state, rather than returning a new empty view.
| func view() -> UIView { | ||
| return uiView ?? UIView() | ||
| } |
There was a problem hiding this comment.
Returning a new, empty UIView when uiView is nil could lead to subtle bugs and unexpected behavior. For instance, the Flutter engine might add this empty view to the view hierarchy, resulting in a blank space where the webview should be, without any clear error indicating what went wrong.
Given the assumption that view() should not be called after the underlying native view is deallocated, it would be more robust to enforce this with a fatalError. This will help catch incorrect usage during development and provide a clear error message.
func view() -> UIView {
guard let uiView = uiView else {
fatalError("The platform view is being accessed after it has been released.")
}
return uiView
}
I'm not sure how this part follows; nothing would prevent the engine from keeping a strong reference to the view returned by Could we instead make sure internally that the proxy system can't ever try to send messages after |
|
@stuartmorgan-g I think the problem is that As I pointed out in this comment, Now that I think about it, we should probably create a separate issue if the binaryMessenger is becoming invalid before plugins are notified.
This is true and I considered this as well. Based on the logs, it looks like the container is deallocated before the native UIView, so I assumed this could work as a quick workaround: But I can probably just close this and work on the fix I talked about in the comment. |
Oof. Sorry, I'd paged that conversation out. Yes, the engine internals being torn down before telling the plugins is definitely bad news. We can give this a try in the short term then, but please add a comment in the code explaining what this code is doing and why, and referencing the issue tracking the engine fix, so that we know when we can remove it again. I'm still somewhat skeptical that this will actually work reliably in practice since UIViews sometimes have lifetime extensions from the system (e.g., if there's an animation happening around the teardown), but we can give it a shot. |
Updates
PlatformViewImplto only store a weak reference to the native view. This issue seems to indicate thePlatformViewsControlleris keeping a reference to the native view even after it is removed from theInstanceManagerinwebview_flutter_wkwebview. This change should allow the pigeon call to happen when the reference to the Dart instance is deallocated. This should be safe because if the Dart instance is deallocated, then the Widget tree should no longer contain the PlatformView. And therefore the native UIView should no longer need to be used. Nor any callbacks that need theUIViewsince it is not on screen.Potential fix for flutter/flutter#168535, but should still update engine to notify plugins that they are detached before setting
PlatformViewsControllerto nil.Pre-Review Checklist
[shared_preferences]///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2