From dec45bb09fc521885ef6bd593a20eca98893d2c9 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 14 Mar 2023 13:27:41 +0300 Subject: [PATCH] Fix macos memory leaks (#2739) * Use a weak reference from WinitView to WinitWindow * Allow patched objc2 version * Add changelog entry --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- src/platform_impl/macos/view.rs | 14 +++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e250fe6152..a06e710281 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased +- Fix macOS memory leaks. + # 0.28.2 - Implement `HasRawDisplayHandle` for `EventLoop`. diff --git a/Cargo.toml b/Cargo.toml index 679b044ab3..39fb186d62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,7 @@ ndk = "0.7.0" [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] core-foundation = "0.9.3" -objc2 = "=0.3.0-beta.3" +objc2 = ">=0.3.0-beta.3, <0.3.0-beta.4" # Allow `0.3.0-beta.3.patch-leaks` [target.'cfg(target_os = "macos")'.dependencies] core-graphics = "0.22.3" diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index e3a8b05e9c..644fcd0a22 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -7,7 +7,7 @@ use objc2::foundation::{ NSArray, NSAttributedString, NSAttributedStringKey, NSCopying, NSMutableAttributedString, NSObject, NSPoint, NSRange, NSRect, NSSize, NSString, NSUInteger, }; -use objc2::rc::{Id, Owned, Shared}; +use objc2::rc::{Id, Owned, Shared, WeakId}; use objc2::runtime::{Object, Sel}; use objc2::{class, declare_class, msg_send, msg_send_id, sel, ClassType}; @@ -136,7 +136,8 @@ declare_class!( #[derive(Debug)] #[allow(non_snake_case)] pub(super) struct WinitView { - _ns_window: IvarDrop>, + // Weak reference because the window keeps a strong reference to the view + _ns_window: IvarDrop>>, pub(super) state: IvarDrop>, marked_text: IvarDrop>, accepts_first_mouse: bool, @@ -167,7 +168,10 @@ declare_class!( forward_key_to_app: false, }; - Ivar::write(&mut this._ns_window, window.retain()); + Ivar::write( + &mut this._ns_window, + Box::new(WeakId::new(&window.retain())), + ); Ivar::write(&mut this.state, Box::new(state)); Ivar::write(&mut this.marked_text, NSMutableAttributedString::new()); Ivar::write(&mut this.accepts_first_mouse, accepts_first_mouse); @@ -873,11 +877,11 @@ impl WinitView { // (which is incompatible with `frameDidChange:`) // // unsafe { msg_send_id![self, window] } - (*self._ns_window).clone() + self._ns_window.load().expect("view to have a window") } fn window_id(&self) -> WindowId { - WindowId(self._ns_window.id()) + WindowId(self.window().id()) } fn queue_event(&self, event: WindowEvent<'static>) {