Skip to content

Commit dec45bb

Browse files
madsmtmkchibisov
authored andcommitted
Fix macos memory leaks (#2739)
* Use a weak reference from WinitView to WinitWindow * Allow patched objc2 version * Add changelog entry
1 parent d102c21 commit dec45bb

File tree

3 files changed

+12
-6
lines changed

3 files changed

+12
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ And please only add new entries to the top of this list, right below the `# Unre
88

99
# Unreleased
1010

11+
- Fix macOS memory leaks.
12+
1113
# 0.28.2
1214

1315
- Implement `HasRawDisplayHandle` for `EventLoop`.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ ndk = "0.7.0"
6868

6969
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
7070
core-foundation = "0.9.3"
71-
objc2 = "=0.3.0-beta.3"
71+
objc2 = ">=0.3.0-beta.3, <0.3.0-beta.4" # Allow `0.3.0-beta.3.patch-leaks`
7272

7373
[target.'cfg(target_os = "macos")'.dependencies]
7474
core-graphics = "0.22.3"

src/platform_impl/macos/view.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use objc2::foundation::{
77
NSArray, NSAttributedString, NSAttributedStringKey, NSCopying, NSMutableAttributedString,
88
NSObject, NSPoint, NSRange, NSRect, NSSize, NSString, NSUInteger,
99
};
10-
use objc2::rc::{Id, Owned, Shared};
10+
use objc2::rc::{Id, Owned, Shared, WeakId};
1111
use objc2::runtime::{Object, Sel};
1212
use objc2::{class, declare_class, msg_send, msg_send_id, sel, ClassType};
1313

@@ -136,7 +136,8 @@ declare_class!(
136136
#[derive(Debug)]
137137
#[allow(non_snake_case)]
138138
pub(super) struct WinitView {
139-
_ns_window: IvarDrop<Id<WinitWindow, Shared>>,
139+
// Weak reference because the window keeps a strong reference to the view
140+
_ns_window: IvarDrop<Box<WeakId<WinitWindow>>>,
140141
pub(super) state: IvarDrop<Box<ViewState>>,
141142
marked_text: IvarDrop<Id<NSMutableAttributedString, Owned>>,
142143
accepts_first_mouse: bool,
@@ -167,7 +168,10 @@ declare_class!(
167168
forward_key_to_app: false,
168169
};
169170

170-
Ivar::write(&mut this._ns_window, window.retain());
171+
Ivar::write(
172+
&mut this._ns_window,
173+
Box::new(WeakId::new(&window.retain())),
174+
);
171175
Ivar::write(&mut this.state, Box::new(state));
172176
Ivar::write(&mut this.marked_text, NSMutableAttributedString::new());
173177
Ivar::write(&mut this.accepts_first_mouse, accepts_first_mouse);
@@ -873,11 +877,11 @@ impl WinitView {
873877
// (which is incompatible with `frameDidChange:`)
874878
//
875879
// unsafe { msg_send_id![self, window] }
876-
(*self._ns_window).clone()
880+
self._ns_window.load().expect("view to have a window")
877881
}
878882

879883
fn window_id(&self) -> WindowId {
880-
WindowId(self._ns_window.id())
884+
WindowId(self.window().id())
881885
}
882886

883887
fn queue_event(&self, event: WindowEvent<'static>) {

0 commit comments

Comments
 (0)