2011-06-12 4 views
2

응용 프로그램 (OS X 10.6.7)에서 NSWindowController 하위 클래스가 -[NSWindowController initWithWindow:] -i.e.로 초기화되며 코드에서 이미 창을 만들었습니다. 나는 펜촉에서 로딩하지 않을거야.- NSWindowController가 윈도우로 초기화되면 [NSWindowController window] 유지 윈도우가 생깁니 까?

보통 NSWindowController 서브 클래스의 창은 [self window]입니다. 그러나이 경우, 내가 [self window]을 보낼 때마다 창은 그대로 유지되므로 꽤 많이 유출됩니다.

이것은 의도 한 동작입니까? 잠시 동안 나는 init 메서드의 인스턴스 변수에 창을 저장하고 절대로 [self window]을 보내는 것으로 해결했습니다. -loadWindow 창 및 -isWindowLoaded 반환 YES 유지되지 않습니다 :

나는 NSWindowController 창로드하려고하기 때문에 이런 일이되지 확신

(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 
+0

'-window'가'return [[_window retain] autorelease]'와 같은 일을 할 수 있으며, 디버깅 세션은 해당 자동 풀이 빠져 나갈 기회를주지 않습니다. _ 누설 된 누수가 있습니까? –

+0

예, 실제 누수가 있습니다. 위의 "닫기 전에"를 참고하십시오. 이것은 창을 닫으려고 할 때 발생하며, 보유 개수는'[self window]'호출의 수에 직접 비례합니다. 나는 이것에 대한 또 다른 언급을 발견했다 : http://www.cocoabuilder.com/archive/cocoa/219582-nswindowcontroller-retain-counts-chapter-2.html –

+1

나는 그 스레드가'-retain/autorelease' 패턴, 그리고 불균형 autorelease 풀 코멘트가 흥미 롭습니다. 그 외에는 아이디어가 없습니다. –

답변

2

-[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 

문제는 내가 탄소 이벤트 핸들러 (InstallApplicationEventHandler)에서 코코아 물건을 할 때 풀을 생성하는 것을 잊었다이었다. 이것은 내가 링크 된 스레드의 컨텍스트와 일치합니다.

일반적으로 autorelease 풀이 존재하지 않을 때 예외가 표시됩니다. 따라서 결코 절대로 흘러 가지 않는 풀이있는 것 같습니다.