我一直在努力解决以下泄漏问题。我通过 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]];
哪里recipient
只是一个 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
是方法中的NSMutableArray
分配/初始化applicationDidFinishLaunching
和释放dealloc
。
在 中NewMessageWindowController
,我使用以下命令通知应用程序委托窗口即将关闭并且不再需要保留控制器:
- (void)windowWillClose:(NSNotification *)notification {
[AppDelegate windowControllerDidFinish:self];
}
应用委托的方法如下所示:
- (void)windowControllerDidFinish:(NSWindowController *)controller {
[windowControllers removeObject:controller];
}
在之前和之后记录数组是我所期望的。控制器在窗口关闭之前就在那里,当窗口关闭时它被移除。
当我关闭窗户时,仪器会发现泄漏。虽然它是开放的,但一切似乎都很好。值得注意的是,在 NewMessageWindowController 中按预期调用了 dealloc。Leaks 并未将控制器本身报告为问题,而是泄漏的对象是 NSCFString,它只是源自上面的代码。
构建和分析没有得到任何东西,我很确定我的内存管理在创建/显示窗口控制器/窗口的代码块上很好。
奇怪的是,如果我使用键盘关闭窗口,只会出现泄漏。如果我单击单击红色关闭按钮,仪器不会拾取任何东西。
最后,Instruments 并不总是表明该代码块是负责任的。在这些情况下,我的代码都没有在 Instruments 中被引用——它似乎都是 AppKit。同样,这仅在我使用键盘关闭窗口(cmd-w)时。
有任何想法吗?