关闭后从数组中删除 NSWindow

Remove NSWindow from array after closing

我正在以编程方式创建 windows,然后在我这样显示它们时将它们添加到数组中。

NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:NO];
window.delegate = self;
window.releasedWhenClosed = YES;    
[window makeKeyAndOrderFront:NSApp];
[_array addObject:window];

我需要在 windows 关闭时从数组中删除它们,但我似乎无法让它工作。如果我像这样从 -windowWillClose: 委托方法中的数组中删除 window,我的应用程序会在委托方法完成后因 EXC_BAD_ACCESS 而崩溃。

- (void)windowWillClose:(NSNotification *)notification
{
    NSWindow *window = notification.object;
    [_array removeObject:window];
}

我相信 window 控制器将在 windowWillClose: 的中间被 ARC 释放。请尝试使用 windowShouldClose:

将 window 的 releasedWhenClosed 属性 设置为 false,而不是 true。

将 属性 设置为 true 本质上会导致超出正常内存管理所涉及的额外释放。如果您使用的是 ARC,那么这个版本太多了,因为 ARC 本身会平衡保留和释放。 (如果您没有使用 ARC,那么该版本将适合平衡您的第一个代码片段中的 +alloc,否则它是不平衡的。但是,即使在那种情况下,我还是建议编写正常的代码,平衡内存管理并将此 属性 设置为 false。)

其次,将 window 的 delegate 属性 设置为 nil,然后再将其从数组中删除。

最后,如果这不能解决问题,请显示崩溃的详细信息,包括堆栈跟踪。

为 NSWindow 创建一个 NSWindowController 并将这些控制器存储在数组中 (NSMutableArray<NSWindowController *>) 而不是 windows 解决了问题。

NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:NO];
window.delegate = self; 
NSWindowController *windowController = [[NSWindowController alloc] initWithWindow:window];
[windowController showWindow:self];
[_array addObject:windowController];

NSWindowDelegate

- (void)windowWillClose:(NSNotification *)notification
{
    NSWindow *window = notification.object;
    [_array removeObject:window.windowController];
}