我一直在努力與下面的泄漏一段時間了。我已經收窄,通過儀器對下面的代碼塊:內存泄漏NSWindowController的showWindow:
- (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
分配/ init'ed在applicationDidFinishLaunching
並在dealloc
方法釋放。
在NewMessageWindowController
,我用下面的通知應用程序代理,窗口即將關閉,而且也沒有必要保留控制器更多:
- (void)windowWillClose:(NSNotification *)notification {
[AppDelegate windowControllerDidFinish:self];
}
應用程序委託的方法是這樣的:
- (void)windowControllerDidFinish:(NSWindowController *)controller {
[windowControllers removeObject:controller];
}
記錄陣列之前和之後是我如何期待它。窗戶關閉前,控制器位於那裏,當窗戶關閉時,控制器將被移除。
當我關閉窗戶時,儀器會檢測到泄漏。雖然它是開放的,但一切似乎都很好。值得注意的是,按預期在NewMessageWindowController中調用dealloc。泄漏不是將控制器本身報告爲問題,而是泄漏的對象是NSCFString,它只是源自上面的代碼。
構建和分析不會挑選任何東西,我很確定我的內存管理在創建/顯示窗口控制器/窗口的代碼塊上很好。
奇怪的是,如果我使用鍵盤關閉窗口,只會有泄漏。如果我點擊紅色的關閉按鈕,樂器不會選擇任何東西。
最後,Instruments並不總是顯示該代碼塊負責。在這些情況下,我的代碼沒有在樂器中引用 - 它似乎都是AppKit。再說一遍,只有當我用鍵盤關閉一個窗口(cmd-w)時纔是如此。
任何想法?
當使用鍵盤或鼠標時,Dealloc確實在NSWindowController中調用。 – 2011-05-25 17:39:47
是儀器說,NewMessageWindowController是對象泄漏?如果是這種情況,並且您看到對象正在交易,這意味着您有一個錯誤的泄漏。稍等片刻後,嘗試重新運行泄漏掃描;泄漏可能會消失。如果對象明顯被釋放,我不會擔心這個泄漏。 – 2011-05-25 21:54:50
樂器正在顯示一個NSCFString作爲泄漏對象,它只是源自showWindow調用(或者Instruments所說的)。 – 2011-05-25 22:43:16