- 当NSWindowController用窗口初始化时,[NSWindowController窗口]保留窗口?

时间:2011-06-12 23:21:25

标签: cocoa nswindowcontroller

在一个应用程序(OS X 10.6.7)中,我有一个用NSWindowController初始化的-[NSWindowController initWithWindow:]子类 - 即,我已经在代码中创建了窗口;我不是从笔尖加载它。

通常情况下,我使用NSWindowController引用[self window]子类中的窗口。但在这种情况下,每次发送[self window]时,窗口都会被保留,所以我最终会泄漏很多。

这是预期的行为吗?目前我只是通过将窗口存储在init方法中的实例变量中并且从不发送[self window]来解决这个问题。

我很确定这种情况没有发生,因为NSWindowController正在尝试加载窗口:-loadWindow没有保留窗口而-isWindowLoaded返回YES

(gdb) set $window = (id)[self window]
Current language:  auto; currently objective-c
(gdb) p (int)[$window retainCount]
$1 = 3
(gdb) p (BOOL)[self isWindowLoaded]
$2 = 1 '\001'
(gdb) call (void)[self loadWindow]
(gdb) p (int)[$window retainCount]
$3 = 3
(gdb) p (int)[[self window] retainCount]
$4 = 4
(gdb) p (int)[[self window] retainCount]
$5 = 5

1 个答案:

答案 0 :(得分:2)

-[NSWindowController window]保留窗户很好;这个问题似乎与自动释放池有关。

window = [[NSWindow alloc] initWithContentRect:NSMakeRect(100, 100, 200, 200)
                                               styleMask:NSTitledWindowMask
                                                 backing:NSBackingStoreBuffered
                                                   defer:NO];
NSWindowController *controller = [[NSWindowController alloc] initWithWindow:window];
[window setTitle:@"testing"];
[window makeKeyAndOrderFront:nil];
[window release];
NSLog(@"[window retainCount]: %d", [window retainCount]);
[controller window];
[controller window];
[controller window];
NSLog(@"[window retainCount]: %d", [window retainCount]);

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[controller window];
[controller window];
[controller window];
NSLog(@"[window retainCount]: %d", [window retainCount]);
[pool drain];
NSLog(@"[window retainCount]: %d", [window retainCount]);

输出结果为:

2011-06-12 19:26:52.337 window[5517:a0b] [window retainCount]: 1
2011-06-12 19:26:52.339 window[5517:a0b] [window retainCount]: 4
2011-06-12 19:26:52.340 window[5517:a0b] [window retainCount]: 7
2011-06-12 19:26:52.340 window[5517:a0b] [window retainCount]: 4

问题是我在Carbon事件处理程序(InstallApplicationEventHandler)中执行Cocoa时忘了创建池。这与我链接的线程的上下文匹配。

通常情况下,当没有自动释放池存在时我会看到一个例外,所以我猜测只有一个永远不会耗尽的游泳池。