可可NSWindowController和NSWindow不取消分配

gng*_*zrd 4 cocoa release dealloc nswindow nswindowcontroller

我正在与NSWindowController一起实现首选项窗口。Apple的文档指出,默认情况下不会释放控制器和窗口,因为不必重新加载所有内容非常有用,这很有意义。但是他们的文档继续说您可以覆盖该行为,但不解释如何做。

苹果的文档:

When a window is closed and it is part of a document-based
application, the document  removes the window’s window
controller from its list of window controllers. This results 
in the system deallocating the window controller and the
window, and possibly the NSDocument object itself. When a
window controller is not part of a document-based application, 
closing the window does not by default result in the
deallocation of the window or window controller. This is the
desired behavior for a window controller that manages something
like  an inspector; you shouldn’t have to load the nib file
again and re-create the objects the  next time the user requests
the inspector.

If you want the closing of a window to make both
window and window controller go away when it isn’t
part of a document, your subclass of NSWindowController
can observe the NSWindowWillCloseNotification notification
or, as the window delegate, implement the windowWillClose: method.
Run Code Online (Sandbox Code Playgroud)

我在windowWillClose:方法中找不到解释“实施”内容的地方。

可以在这里看到窗口控制器:https : //github.com/gngrwzrd/gwpreferences/blob/master/GWPreferences/GWPreferences/GWPreferences/GWPrefsWindowController.m

可以在此处看到使用控制器的信息:https : //github.com/gngrwzrd/gwpreferences/blob/master/GWPreferences/GWPreferences/GWAppDelegate.m-您可以在此代码中看到我正在尝试进行强制转换的桥梁释放对象,但不起作用。

因此,GWPrefsWindowController.dealloc方法永远不会被调用。有任何想法吗?

Bru*_*ira 5

我知道这个问题很旧,但是对于那些来自google的人来说,答案很简单。

如文档中所述,对于非基于文档的应用程序,您可以简单地:

  • NSWindowController随时随地为您提供参考。(在下面的示例中,该引用由myWindowController;
  • 使类调用您NSWindowController实现的协议NSWindowDelegate;
  • 通过将windowWillClose:方法设置为nil来释放Window Controller

为了更精确地回答问题。延迟实例化控制器时,将您的类设置为委托:

-(IBAction)showMyWindowAction:(id)sender
{
    // If my window controller is not nil
    if (!myWindowController)
    {
        //instantiate it
        myWindowController = [[MyWindowController alloc] initWithWindowNibName:@"myWindow"];
        // set your class as delegate
        [myWindowController setDelegate:self];
     }

     [myWindowController.window orderFront:self];
}
Run Code Online (Sandbox Code Playgroud)

然后windowWillClose:NSWindowDelegate协议中实现方法

-(void)windowWillClose:(NSNotification *)notification
{
     //Check if it's the right window that will close
     if ([notification.object isEqualTo:myWindowController.window])
     {
         //Set your controller to nil
         myWindowController = nil;
      }
}
Run Code Online (Sandbox Code Playgroud)

就是这样,您的窗口控制器现在将取消分配,并且由于我们正在显示窗口之前验证它的控制器是否为nil,所以一切正常!

我相信默认情况下不执行此操作的原因是因为该initWithWindowNibName:操作比较繁琐,因此您必须考虑对窗口中的所有内容进行重新分配是否会比加载窗口nib文件或多或少受到影响。

希望对您有所帮助