【问题标题】:-[NSWindowController window] retaining window when NSWindowController initialized with window?-[NSWindowController 窗口] NSWindowController 用窗口初始化时保留窗口?
【发布时间】:2011-06-12 23:21:24
【问题描述】:

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

通常,我使用[self window] 引用NSWindowController 子类中的窗口。但是在这种情况下,每次我发送[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

【问题讨论】:

  • 可能是-window 做了类似return [[_window retain] autorelease] 的事情,而您的调试会话并没有给相应的自动释放池耗尽的机会。是否存在实际泄漏?
  • 是的,确实存在泄漏。注意上面的“关闭前”;当我试图关闭窗口时会发生这种情况,并且保留计数与[self window] 调用的数量成正比。我刚刚也发现了另一个提及:cocoabuilder.com/archive/cocoa/…
  • 我看到线程已经覆盖了-retain/-autorelease 模式,并且不平衡的自动释放池评论很有趣。除此之外,我没有想法。
  • 谢谢,回过头来,你是对的。

标签: cocoa nswindowcontroller


【解决方案1】:

-[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 时忘记创建池。这与我链接到的线程的上下文相匹配。

通常,当没有自动释放池存在时,我会看到一个异常,所以我猜只是有一个永远不会耗尽的池。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多