From d7c367e7e9a1437ec4a36f0957419fbea82cd245 Mon Sep 17 00:00:00 2001 From: Ryan McGrath Date: Mon, 23 Mar 2020 21:16:13 -0700 Subject: [PATCH] Experimenting with Drop logic - will extend to View/etc if it works fine with Window. I... think it will. --- appkit/window/mod.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/appkit/window/mod.rs b/appkit/window/mod.rs index ab1ab51..8fe191f 100644 --- a/appkit/window/mod.rs +++ b/appkit/window/mod.rs @@ -242,20 +242,28 @@ impl Window where T: WindowDelegate + 'static { } } -/*impl Drop for Window { +impl Drop for Window { /// When a Window is dropped on the Rust side, we want to ensure that we break the delegate /// link on the Objective-C side. While this shouldn't actually be an issue, I'd rather be /// safer than sorry. /// /// We also clean up our loopback pointer that we use for callbacks. + /// + /// Note that only the originating `Window` carries the internal callback ptr, and we + /// intentionally don't provide this when cloning it as a handler. This ensures that we only + /// release the backing Window when the original `Window` is dropped. + /// + /// Well, theoretically. fn drop(&mut self) { - unsafe { - if let Some(objc_controller) = &self.objc_controller.0 { - let window: id = msg_send![*objc_controller, window]; - let _: () = msg_send![window, setDelegate:nil]; - } + if let Some(ptr) = self.internal_callback_ptr { + unsafe { + // Break the delegate - this shouldn't be an issue, but we should strive to be safe + // here anyway. + let _: () = msg_send![&*self.objc, setDelegate:nil]; - let _ = Rc::from_raw(self.internal_callback_ptr); + // Bring this back and let it drop naturally. + let _ = Rc::from_raw(ptr); + } } } -}*/ +}