2011-10-03 2 views
1

버튼을 터치했을 때 하위보기를 생성하려는 기본보기가있는 앱에서 작업하고 있습니다. 따라서 button 이벤트를 받으면 MainViewController는 initWithNibName을 호출하고 ChildViewController를 ivar에 저장하여 자식 뷰를 생성합니다. 그런 다음 애니메이션을 첨부하고 childVC.view.hidden = NO로 설정하여 ChildView를 표시합니다.왜 initWithNibName을 사용할 때 UIViewController가 여분의 시간을 유지합니까?

이 작동하지만 ChildView를 닫은 후에 ChildViewController가 해제되지 않은 것으로 나타났습니다. ChildVC의 보유 횟수가 처음으로 하위보기에 액세스 할 때 1에서 2로 바뀌 었음을 알았습니다. 그래서 박테리아를로드하는 용기에 무언가는 ChildVC를 다시 유지하는 것으로 보입니다 (객체 초기화 중에 예상되는 초기 보유 외에도).

누군가 내가 ChildVC가 여분의 시간을 유지하는 이유를 알아낼 수 있습니까? 어떻게하면 하위 뷰를 닫을 때 완전히 릴리스되는지 확인할 수 있습니까?

편집 : 여기 약간의 코드가 있지만 약간만 간략화되었습니다. 부모 뷰 컨트롤러의 메소드입니다. 코드없이

-(IBAction)onLaunchChildButtonTouched:(id)sender 
{ 
    m_childViewController = [[ChildViewController alloc] initWithNibName:@"ChildViewController" bundle:nil]; 
    [m_childViewController setParentDelegate:self]; // this is a weak reference 

    // m_childViewController retain count here is 1, as expected 
    m_childViewController.view.hidden = YES; 
    // m_childViewController retain count is now 2, not expected 

    [self.view addSubview:m_childViewController.view]; 

    [self addTransitionEntrDir:YES]; // code omitted 

    m_childViewController.view.hidden = NO; 

} 


-(void)onChildWantsToClose:(id)child 
{ 
    NSAssert(child == m_childViewController, @"unexpected childVC"); 

    // if child view is now hidden, we should remove it. 
    if(m_childViewController != nil && m_childViewController.view.hidden) 
    { 
     [m_childViewController.view removeFromSuperview]; 
     [m_childViewController release]; m_childViewController = nil; 

     // BUG: m_childViewController retain count is still 1 here, so it never gets released 

    } 
} 
+0

은 실제 코드를 표시 할 수 있습니까? – Vladimir

+0

일부 코드를 표시하면 A를이 Q로 가져 오는 데 도움이됩니다. – chown

+0

일부 코드가있는 원본 게시물이 업데이트되었습니다. – gga80

답변

0

정확히 말하기는 어렵지만, 당신은 당신이 다른 객체의 당신의 ChildVCretain 속성을 지정하지 않는 확신? 이것은 예기치 않은 retain을 설명합니다.

이전 답변에 대해 유감스럽게도이 동일한 메시지를 전달하려고했지만 모든 것을 혼합했습니다.

OLD 답변 : UIViewControllerview 속성이 유지됩니다 것을 명심 : 보기

컨트롤러가 관리하는보기.

@property (비 원자, 유지)의 UIView * 그래서보기 하면 이런 식으로 할당하는 경우 : childVC.view = [xxxxx는 ALLOC] initWithNibName ...]; 여기에 표시되는 내용이 설명되어 있습니다. 대신 사용 : childVC.view = [[[xxxxx alloc] initWithNibName : ...] autorelease];

+0

답변 해 주셔서 감사합니다. 보기가 아닌 ViewController 초기화 initWithNibName 사용하고 있습니다. 그런 다음 (문서에 따르면) View 속성은 처음 액세스 할 때 펜촉에서 자동으로로드됩니다.ViewController를 자동 렌더링하지는 않지만 자식 뷰가 닫힌 경우 수동으로 해제합니다. 문제는 ChildVC가 추가 시간을 유지하려고하는 것으로 보이며 그 이유를 파악할 수 없습니다. – gga80

0

나는 누수 된 ChildViewController가 ref를 유지 한 객체를 인스턴스화하는 중 문제를 발견했습니다.

재미있는 부분은 내가이 참조를 공개하는 것을 잊지 않고 있다는 것입니다. 나는 그것을 공개 할 호출이 있었지만 viewDidUnload가 실행되어 모든 것을 릴리스 할 수있는 기회를 제공한다고 가정했기 때문에이 코드는 실행되지 않았습니다. dealloc 내부에 deinit 코드를 대신 넣었습니다. 이제 작동합니다.

+0

공통 영역은'addObserverForName : object : queue : usingBlock :'을'viewDidLoad' 내부의'NSNotificationCenter'에'self'에 대한 참조와 함께 사용하지만'dealloc' 내부의 removeObserver 만 사용하면됩니다. Dealloc은 정의에 의해 호출되지 않습니다. 왜냐하면 블록은 'self'를 보유 할 것이기 때문입니다. 이 문제를 해결하거나'viewWillAppear'와'viewDidDisappear' 등에서 알림을 구독/구독 취소하기 위해'self'에 대한 약한 참조를 만들 수 있습니다. –

관련 문제