2013-04-16 6 views
3

매우 기본적인 응용 프로그램입니다 : NSOutlineViewNSTreeController에 바인딩 된 창이 있습니다. 개요보기는 간단한 모델 객체 (TCCard)를 표시합니다. 두 개의 버튼을 추가하여 개요보기에서 모델 객체를 추가하거나 제거 할 수 있습니다.NSOutlineView/NSTreeController는 모든 모델 객체를 제거한 후에이를 해제하지 않습니다.

Instruments (Leaks)의 앱을 보면 내 모델 객체의 새 인스턴스가 추가 될 때 생성된다는 것을 알 수 있지만 개요보기에서 삭제할 때 모두 해제되지는 않습니다. 윤곽선 뷰에 더 이상 항목이없는 경우에도 내 모델 객체의 두 개 또는 세 개의 인스턴스가 항상 "생존"상태로 유지됩니다.

아웃 라인보기 또는 트리 컨트롤러가 장면 뒤에서 캐싱을 수행합니까? 아래 코드 :

#import "TCAppDelegate.h" 

#import "TCCard.h" 

@implementation TCAppDelegate 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    TCCard *first = [TCCard new]; 
    first.title = @"First card"; 

    // tree controller content is bound to self.cards: 
    self.cards = [@[first] mutableCopy]; 
} 

- (IBAction)addCard:(id)sender; 
{ 
    TCCard *second = [TCCard new]; 
    second.title = [NSString stringWithFormat:@"%ld card", self.cards.count]; 

    [self.treeController addObject:second]; 
} 

- (IBAction)deleteCard:(id)sender; 
{ 
    NSIndexPath *path = [NSIndexPath indexPathWithIndex:self.cards.count - 1]; 

    [self.treeController setSelectionIndexPath:nil]; 

    [self.treeController removeObjectAtArrangedObjectIndexPath:path]; 

    // some model objects continue to live 
} 

@end 

아주 기본적인 예입니다. 내 실제 애플 리케이션에서 그 모델 객체는 다른 객체에 대한 많은 참조로 상당히 무겁다. 나는 그들이보기에서 제거 될 때 모두 진짜 풀어 놓고 싶습니다.

편집 :이 문제는 심지어 애플의 샘플 코드를 재현 할 수 있습니다 : 악기의 예에서 https://developer.apple.com/library/mac/#samplecode/DragNDropOutlineView/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008831

실행 및 SimpleNodeData를 검색합니다. 인스턴스 수를 확인한 다음 컨텍스트 메뉴를 통해 예제 응용 프로그램에서 모든 노드를 삭제하십시오.

+0

보기 기반 개요보기를 사용하고 있습니까? 그렇다면 셀보기가 캐시되고 이러한보기에 다른 개체에 대한 바인딩이있는 경우 개체가 예기치 않게 살아있을 수 있습니다. 대리자 메서드 -outlineView : didRemoveRowView : forRow :를 사용하여 행의 셀 뷰를 가져오고 해당 objectValue를 nil로 설정하고 바인딩을 지우고 객체를 릴리스 할 수 있습니다. –

답변

0

- (IBAction)addCard:(id)sender 메서드에서 [TCCard new]을 사용하여 새 TCCard 개체를 할당하면 명시 적으로 릴리스해야하는 개체가 제공됩니다. 트리 컨트롤러는 추가 한 객체를 유지하므로 [treeController addObject:]을 호출 한 후 해제해야합니다. 이처럼 :

- (IBAction)addCard:(id)sender; 
{ 
    TCCard *second = [TCCard new]; 
    second.title = [NSString stringWithFormat:@"%ld card", self.cards.count]; 
    [self.treeController addObject:second]; 
    [second release]; 
} 

팁 : 제품 소개> 미래에 버그 이런 종류의 dedect하는 엑스 코드에서 분석합니다.

+0

고맙지 만 ARC를 사용하고 있으므로 컴파일러가 release/autorelease 호출을 추가합니다. – Mark