2009-11-18 3 views
2

내 응용 프로그램에서 메모리 누수가보고되었지만 정확히 무슨 일이 일어나고 있는지 추적 할 수 없습니다. 이전보기를 가져 와서 새로운보기로 전환하는 기능이 있습니다. NavControllers 또는 @properties를 사용하지 않습니다. 최상위 창을 직접 관리하고 있습니다. 코드를 실행하면코코아 메모리 누수 추적

-(void)swapInView:(UIViewController*)newViewController 
{ 
    [currentViewer.view removeFromSuperview]; 
    printf("Old viewController (%p) has count of %d; now releasing\n", 
     currentViewer, [currentViewer retainCount]); 
    [currentViewer release]; 
    currentViewer = 0; 

    currentViewer = newViewController; 
    [currentViewer retain]; 

    [mainWindow addSubview:currentViewer.view]; 
    [mainWindow bringSubviewToFront:currentViewer.view]; 
} 

, 나는 현재 뷰 컨트롤러가 해제되고 있으며, 그 뷰 컨트롤러 내의 dealloc 메서드가 호출지고 있음을 보여준다. 그러나 계측기/누출은 여전히 ​​누수로보고합니다. 예를 들어, 나는이 인쇄를 얻을 :

Old viewController (0x119f80) has count of 1; now releasing 
Deallocating WelcomeScreenViewController 

나는이 이전에 할당되는 같은 객체인지, 주소에서 확인할 수 있습니다.

MyViewController *theViewController = [[MyViewController alloc] 
             initWithNibName:nil 
               bundle:nil]; 
[GameMaster swapInNewView:theViewController]; 
[theViewController release]; 

아무도 무슨 일이 일어나고 있는지 추적하는 방법에 대한 제안 사항이 있습니까 :

내 외부 코드는 다음과 같이 보인다? 3.1.2 SDK를 사용하고 있지만 이전 SDK에서도이 기능을 볼 수있었습니다.

+0

인스트루먼트는 어떤 특정 라인에서 누설이 발생한다고 말합니까? –

+0

[mainWindow addSubview : currentViewer.view]; –

+0

그래서'mainWindow'가 추가 된 하위 뷰를 유출하고있는 것으로 보입니다. 어떤 시점에서'mainWindow'에서 릴리스를 호출합니까? –

답변

3

허. 이것은 재미있는 하나였다. 나는 우리 둘 중 누구도 정신병자가 아니 었는지 확인하기 위해 빠른 테스트를 썼다. 결국

는, 모든 호출 코드에 온다 :

[[MyViewController alloc] initWithNibName:nil bundle:nil]; 

당신이보기 컨트롤러를 초기화

, 그 view 객체가 아직 정의되지 않았으며, 요청까지 정의되지 않습니다.

nib 이름에 nil을 지정 했으므로 뷰 객체를 올바르게 설정하려면 UIViewController 서브 클래스에서 loadView을 대체해야합니다. 자세한 내용은 Apple's documentation을 참조하십시오.

loadView의 기본 구현은 배후의 마술을 분명히하고, 그 마법은 메모리 누출을 초래할 수 있습니다.

그래서 :

[mainWindow addSubview:currentViewer.view]; 

당신은 실제로 호출하고 있습니다 :

하나 : 당신이 호출 할 때 currentViewer.view[currentViewer loadView]에 대한 호출 결과 및
2 : [mainWindow addSubview:...] 이는 새로로드 된 뷰를 추가하려고 시도합니다.

누수는 첫 번째 호출로 인해이 행을 식별하고 두 번째 호출은 식별하지 않습니다.

은 단순히 사용자 정의 UIViewController 서브 클래스에 loadView 방법을 수정, 확인하려면

- (void)loadView 
{ 
    [self setView:[[UIView new] autorelease]]; 
} 

이것은 기본 loadView에 전화를 방지하고 이제 더 이상 누출이 없습니다.

분명히이 응용 프로그램을 더 개발하면 loadView에 더 의미있는 것을 넣거나 nibs를 사용해야합니다.

+0

환상적! 그것은 고정 된 것으로 보인다. 그것은 결국 (예기치 않게 Apple의 샘플 코드에서이 코드를 복사하여) initWithNibName에 "nil"을 전달하면 클래스와 동일한 이름의 nib 파일을 찾아로드합니다. 그러나, 그것은 분명히 메모리를 누설합니다 ... –

0

참고는 removeFromSuperview 방법에 대한 설명서 :

는 "그 커서 사각형을 리스폰 더 체인에서 제거, 자사의 슈퍼 뷰와 창에서 수신기 링크를 해제하고, 무효화 수신기도 해제됩니다."

내 응용 프로그램에서

[exampleViewController.view removeFromSuperview]; 
[exampleViewController release]; 

인해 객체를 해제 오버에 지연 충돌이 발생 :이 문제 여부,하지만 일입니다 있는지 확실하지 않습니다.

+0

사실, 설정하고 나면 제거한 후에 release하는 것은 사실입니다. 추락하지 마라. –