Skip to content

NSPanel deallocated on .close even with setReleasedWhenClosed(false) #785

@Elawphant

Description

@Elawphant

Description:
In Rust using objc2, dropping a Retained deallocates the panel even when setReleasedWhenClosed(false) (the default). According to Apple docs, the panel should remain retained by AppKit unless setReleasedWhenClosed(true) is set. This behavior differs from Objective-C/Swift expectations and is relevant for memory management in Rust. Also setting it to true, crashes the app on closing the window.

Minimal Repro Example:

use std::sync::{Arc, RwLock};
use objc2::{define_class, rc::Retained, MainThreadMarker};
use objc2_app_kit::NSPanel;

define_class!(
    #[unsafe(super = NSPanel)]
    #[thread_kind = MainThreadOnly]
    #[derive(Debug)]
    pub struct TestPanel;

    impl TestPanel {
        #[unsafe(method(close))]
        fn close(&self) {
            println!("Panel closed");
            unsafe { let _: () = objc2::msg_send![super(self), close]; }
        }
    }
);

impl TestPanel {
    pub fn new() -> Retained<Self> {
        let mtm = MainThreadMarker::new().unwrap();
        let panel = Self::alloc(mtm).set_ivars(());
        unsafe { objc2::msg_send![super(panel), init] }
    }
}

impl Drop for TestPanel {
    fn drop(&mut self) {
        println!("Panel dropped");
    }
}

fn main() {
    let panel = TestPanel::new();
    panel.close(); // Prints "Panel closed (windowWillClose), Prints "Panel dropped" even without setReleasedWhenClosed(true)
}

Observed Behavior:

  • "Panel closed" prints.
  • "Panel dropped" prints immediately after dropping the Rust Retained.
  • Panel is deallocated even though setReleasedWhenClosed(false) was never set, checked with NSZombieEnabled = "YES"

Expected Behavior (according to Apple docs):

Environment:

  • macOS 15.6.1
  • objc2-app-kit version 0.3.1

Notes:

  • This behavior appears safe, but differs from the ObjC documentation.
  • Useful for clarifying Rust + objc2 memory semantics.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-frameworkAffects the framework crates and the translator for themquestionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions