【问题标题】:NSApplication windows property - windows not removed?NSApplication windows 属性 - windows 没有被删除?
【发布时间】:2013-01-01 10:44:58
【问题描述】:

我有一个显示模式的 NSWindow/Controller。它有一个“关闭”按钮连接到这样的操作:

- (IBAction)close:(id)sender
{
    [self.window orderOut:sender];
    [self.window close];

    [[NSApplication sharedApplication] stopModal];
}

在我的主窗口中,我显示模态:

- (IBAction)modal:(id)sender
{
    NSLog(@"Before: %lu", [[[NSApplication sharedApplication] windows] count]);

    ModalWindowController *modal = [[ModalWindowController alloc] initWithWindowNibName:@"ModalWindowController"];
    [[NSApplication sharedApplication] runModalForWindow:modal.window];

    NSLog(@"After: %lu", [[[NSApplication sharedApplication] windows] count]);
}

我打开和关闭了几次modal,输出是这样的:

2013-01-17 14:36:08.071 Modals[3666:303] Before: 1
2013-01-17 14:36:08.962 Modals[3666:303] After: 2
2013-01-17 14:36:09.578 Modals[3666:303] Before: 2
2013-01-17 14:36:11.009 Modals[3666:303] After: 3
2013-01-17 14:36:12.108 Modals[3666:303] Before: 3
2013-01-17 14:36:12.910 Modals[3666:303] After: 4

所以,[[[NSApplication sharedApplication] windows] count]只会增加

我希望它随着我打开和关闭模式窗口而增加和减少。我的应用程序使用 ARC。谁能给我解释一下?

提前谢谢你

【问题讨论】:

  • [window isReleasedWhenClosed] 返回什么?模态显示为工作表还是顶级模态弹出窗口?
  • 窗口被设置为在关闭时释放。事实证明,我没有在这个项目上启用 ARC,所以控制器仍然被保留。谢谢!
  • 好的,所以问题是您认为您使用的是 ARC,但不是吗?是的,这将导致各种泄漏......
  • 我在 XCode 中工作不多,出于某种原因,我一直认为 ARC 这些天是默认启用的
  • 是的。除非您使用的是相当旧的 Xcode 版本(在这种情况下,“这些天”不相关),当您创建一个新项目并选择 Cocoa 应用程序时,“使用自动引用计数”复选框默认情况下处于启用状态。除非你把它关掉,否则你会明白的。 (而且,与 Xcode 3 不同,我认为甚至没有任何方法可以更改您的首选项中的默认值……)

标签: objective-c macos cocoa appkit


【解决方案1】:

您正在关闭窗口,但这并没有取消分配它,因为您的窗口控制器ModalWindowController 仍在保留它。我在您的示例中没有看到任何表明正在释放窗口控制器的内容。

给你的最简单的答案是让你在调用-runModalForWindow:之后释放你的窗口控制器。

您可能期望窗口控制器在您的窗口关闭时关闭。这是你必须自己做的事情。来自 Apple 文档中的“Window Closing Behavior”:

如果你想让一个窗口的关闭同时使窗口和窗口 当控制器不是文档的一部分时,控制器就会消失,您的子类 NSWindowController 可以观察 NSWindowWillCloseNotification 或者,作为 窗口委托,实现 windowWillClose: 方法并包含 实现中的以下代码行:“[self autorelease];”

在您的场景中,这可能不是最好的方法,因为在您有机会致电-stopModal 之前,您最终会处理掉您的窗口控制器和窗口。

【讨论】:

  • 这是正确答案。添加对 [modal release] 的调用可以解决问题……事实证明,我没有为该项目启用 ARC。哦!谢谢。
【解决方案2】:

看看这个NSWindow方法:

- (void)setReleasedWhenClosed:(BOOL)releasedWhenClosed;

如果您将其设置为 YES,您的窗口将在关闭时被释放。但请注意,当计数为零时,它将被释放。

【讨论】:

  • 窗口被设置为在关闭时释放。事实证明,我没有在这个项目上启用 ARC,所以控制器仍然被保留。谢谢!
【解决方案3】:

对于 Swift 5 人来说,这对我有用。在这种情况下,我想正确关闭每个窗口,除非它是最后一个窗口,在这种情况下我希望它隐藏

  func windowShouldClose(_ sender: NSWindow) -> Bool {
    sender.isReleasedWhenClosed = true
    if NSApp.windows.count > 1 {
        return true
    }
    NSApp.hide(nil)
    return false
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2011-05-26
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多