私はしばらくの間、次のリークに苦しんでいます。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];
}
前後の配列をログに記録することは、私が期待する方法です。コントローラはウィンドウが閉じる前にそこにあり、ウィンドウが閉じると削除されます。
窓を閉めると、機器が漏れを拾います。開いている間は、すべてが正常に見えます。期待どおり、DeallocがNewMessageWindowControllerで呼び出されていることに注意してください。リークはコントローラー自体を問題として報告していません。代わりに、リークしているオブジェクトはNSCFStringであり、上記のコードから発生しているだけです。
Build and Analyzeは何も検出していません。また、ウィンドウコントローラー/ウィンドウを作成/表示するコードのブロックでメモリ管理が正常に行われていると確信しています。
奇妙なことに、キーボードを使用してウィンドウを閉じた場合にのみリークが発生します。赤い閉じるボタンをクリックしても、Instrumentsは何も検出しません。
最後に、Instrumentsは、そのコードブロックが責任を負うことを常に示しているわけではありません。そのような場合、Instrumentsで私のコードは参照されていません。すべてAppKitのようです。繰り返しますが、これはキーボードを使用してウィンドウを閉じる場合のみです(cmd-w)。
何か案は?