关闭后从阵列中删除NSWindow

时间:2015-10-20 04:10:00

标签: objective-c cocoa nswindow

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

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];

我需要在关闭时从阵列中删除窗口,但我似乎无法使其工作。如果我在-windowWillClose:委托方法中删除了我的数组中的窗口,那么我的应用程序在委托方法完成后会与EXC_BAD_ACCESS崩溃。

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

3 个答案:

答案 0 :(得分:3)

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

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

其次,在将窗口的delegate属性从数组中删除之前,将其设置为nil

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

答案 1 :(得分:1)

为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];
}

答案 2 :(得分:0)

我相信在windowShouldClose:的中间,ARC将取消分配窗口控制器。请尝试使用content.toplevelcontainer