NSWindowController的showWindow:内存泄漏

| 我一直在努力应对以下泄漏。我通过Instruments将其范围缩小到以下代码块:
- (NewMessageWindowController *)showNewMessageWindowWithRecipients:(NSArray *)recipients {

    NewMessageWindowController * newMessageWindowController = [[NewMessageWindowController alloc] init];
    [newMessageWindowController showWindow:self]; // 100% on this line.
    [newMessageWindowController.toField setStringValue:[recipients componentsJoinedByString:@\",\"]];
    [newMessageWindowController.messageView becomeFirstResponder];
    [windowControllers addObject:newMessageWindowController];
    [newMessageWindowController release];

    return newMessageWindowController;
}
该块的调用方式如下:
[AppDelegate showNewMessageWindowWithRecipients:[NSArray arrayWithObject:recipient]];
其中ѭ2just只是一个NSString。 这是乐器的回溯:
  30 Friendz start
  29 AppKit NSApplicationMain
  28 AppKit -[NSApplication run]
  27 AppKit -[NSApplication sendEvent:]
  26 AppKit -[NSWindow sendEvent:]
  25 AppKit -[NSWindow keyDown:]
  24 AppKit forwardMethod
  23 Friendz -[FriendzAppDelegate showNewMessageWindowWithRecipients:] /Path/To/FriendzAppDelegate.m:226
  22 AppKit -[NSWindowController showWindow:]
  21 AppKit -[NSWindow makeKeyAndOrderFront:]
  20 AppKit -[NSWindow _makeKeyRegardlessOfVisibility]
  19 AppKit -[NSWindow _changeKeyAndMainLimitedOK:]
  18 AppKit -[NSWindow becomeKeyWindow]
  17 AppKit _NXResetCursorState
  16 AppKit +[NSEvent _discardCursorEventsForWindowNumber:criteria:]
  15 HIToolbox FlushSpecificEventsFromQueue
  14 HIToolbox PullEventsFromWindowServer
  13 HIToolbox PullEventsFromWindowServerOnConnection(unsigned int, unsigned char)
  12 HIToolbox ConvertPlatformEventRecordAndPostWithOptions(__CGEvent*, _CGSEventRecord const*, short, unsigned char, unsigned char)
  11 HIToolbox PostEventToQueueInternal
  10 HIToolbox _NotifyEventLoopObservers
   9 HIToolbox KeyEventPostedObserver
   8 HIToolbox TSMProcessRawKeyCode
   7 HIToolbox TSMTranslateKeyEvent
   6 HIToolbox GetDataFromUCHRForEvent
   5 HIToolbox ConvertEventUniCharsToCharCodes
   4 HIToolbox utGetInputSourceScriptInfo
   3 CoreFoundation CFLocaleCreateCanonicalLocaleIdentifierFromScriptManagerCodes
   2 CoreFoundation CFStringCreateWithCStringNoCopy
   1 CoreFoundation __CFStringCreateImmutableFunnel3
   0 CoreFoundation _CFRuntimeCreateInstance
windowControllers
是in6ѭ中的
NSMutableArray
分配/初始化,并以
dealloc
方法释放。 在ѭ8中,我使用以下命令通知应用程序代表该窗口即将关闭,并且不再需要保留控制器:
- (void)windowWillClose:(NSNotification *)notification {
    [AppDelegate windowControllerDidFinish:self];
}
应用程序委托的方法如下所示:
- (void)windowControllerDidFinish:(NSWindowController *)controller {
    [windowControllers removeObject:controller];
}
我之前和之后都在记录数组,这是我期望的样子。控制器在窗口关闭之前就已经在其中,当窗口关闭时它已被删除。 当我关闭窗户时,仪器会吸收泄漏。它打开时,一切似乎都很好。值得注意的是,正如预期的那样,已在NewMessageWindowController中调用了dealloc。泄漏并没有将控制器本身报告为问题,而是泄漏的对象是NSCFString,它仅源于上面的代码。 Build and Analyze没做任何事情,我很确定我的内存管理在创建/显示窗口控制器/窗口的代码块上是可以的。 奇怪的是,如果我使用键盘关闭窗口,只会发生泄漏。如果单击单击红色的关闭按钮,则乐器不会拾取任何东西。 最后,Instruments并不总是显示该代码块负责。在这些情况下,Instruments中没有引用我的代码-它似乎全部是AppKit。同样,这仅在我使用键盘关闭窗口(cmd-w)的情况下进行。 有任何想法吗?     
已邀请:

bab

在这种情况下,我将使用Xcode4中的Instruments版本,配置分配工具以记录保留/释放事件。对于该特定控制器,这应该向您显示为什么它的保留计数不会为零。请注意,对于基于鼠标和基于键盘的关闭,可能会执行不同的代码路径。     
这是因为您无法指望在对象被“销毁”时可靠地调用dealloc-可能是由于某种原因使用键盘比单击对象时不太可能导致立即调用dealloc。 X?     

要回复问题请先登录注册