2013-12-24 1 views
0

사용자가 버튼을 클릭하고 뷰를 전환 할 수 있어야하는 애플리케이션을 작성 중입니다. IBActions 원하는 뷰에 내 메서드 switchSubView를로드했지만 그렇게 할 때 몇 가지 문제가 발생했습니다. 인터페이스 작성기를 통해 IBOutlets로 연결된 두 개의 NSViews 사이의 전환을 애니메이션으로 만드는 메소드를 작성했습니다. 두 가지보기간에 전환하는 방법을 사용할 수 있지만 처음보기에서 다른보기로 전환 한 다음 다른보기로 전환하고 다시 전환하려고하면 EXC_BAD_ACCESS이 표시됩니다. 문제를 디버그 할 수 없습니다. 디버거는 NSView 두 개체가 서로 다른 메모리 위치를 가리 키도록 보여줍니다. 명확히하기 위해 응용 프로그램의 실행 기간 동안보기를 재사용하고 싶습니다. 할당 취소 할보기가 마음에 들지 않습니다. initialView와 newView 부여, 기본적으로이 NSView가 잘못된 액세스 오류를 일으키기 위해 할당 해제되는 위치는 어디입니까?

- (void)switchSubViews:(NSView *)firstView withView:(NSView *)secondView { 
    [firstView setSubviews:[NSArray array]]; 
    [self prepareViews:firstView]; 
    [[firstView animator] addSubview:secondView]; 
} 

/* Make a "move" animation effect. */ 
- (void)prepareViews:(NSView *)prepareView { 
    CATransition * transition = [CATransition animation]; 
    [transition setType:kCATransitionPush]; 
    [transition setSubtype:kCATransitionFromRight]; 
    [prepareView setAnimations:[NSDictionary dictionaryWithObject:transition forKey:@"subviews"]]; 
    [prepareView setWantsLayer:YES]; 
} 

, 나는 이런 식으로 부를 것이다 : :

이 가 가
[self switchSubViews:initialView withView:newView]; 
가 가 가

사람이 날이 디버깅 도와 드릴까요 여기

코드인가?

감사합니다.

업데이트 : for 루프 및 removeFromSuperview 코드를 디버깅하여 주석 처리 한 후에도 여전히 잘못된 액세스 오류가 발생합니다. 보기의 속성은 @property (nonatomic, strong)으로 설정되므로보기가 유지되지 않아야합니까? 그렇지 않은 경우 어떻게 ARC를 활성화하여 NSView를 명시 적으로 유지할 수 있습니까? ARC에 그것을 유지하도록 말할 수 있습니까? 아니면 @property (비 원자력, 강함)로 설정 되었기 때문에 이미 뷰를 유지하고 있습니까?

두 번째 업데이트 : 조금 연구 한 결과 ARC가 개체에 대한 강력한 포인터를 만들어 개체를 유지할 수 있음을 알았습니다. 나는 인스턴스 변수를 작성하여 그것을 시도 :

@interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> { 
    /* Some instance variables here... */ 
    __strong NSView * retainFirstView; 
    __strong NSView * retainSecondView; 
} 

@property (nonatomic, strong) NSView * retainFirstView; 
@property (nonatomic, strong) NSView * retainSecondView; 

그리고 다음하는 .m 파일 :

#import <Quartz/Quartz.h> /* Animation. */ 
#import "AppDelegate.h" 
/* Some other imports necessary... */ 

@implementation AppDelegate 

@synthesize retainFirstView; 
@synthesize retainSecondView; 

/* Some subview switching code... */ 
[self setRetainFirstView:firstView]; 
[self setRetainSecondView:secondView]; 

@end 

하지만 난 여전히 오류가 발생합니다. 내가 바꾼다는 견해가 끊임없이 할당 해제 된 것으로 보인다. 나는 이것에 상당한 시간을 할애 해 오류를 없앨 수 없었다. 어떤 도움을 주시면 감사하겠습니다. 이것이보기를 유지하는 적절한 방법이 아니라면 알려 주시기 바랍니다.

업데이트 3 :

[firstView retain]; 
[secondView retain]; 

하고 여전히 실패 나는 일시적으로 비활성화 ARC를 가지고 setSubviews 또는 addSubview를 호출하기 전에 이런 짓을 테스트합니다. 나는 더 이상 할당 해제를 일으킬 수있는 것을 보지 못해서 매우 혼란 스럽습니다.

업데이트 4 :은 내가하고 제품에 의해 해제 된 객체로 전송 좀비와 메시지 확인 -> 회원 엑스 코드, 그리고 놀랍게도, 나는 어떤 통보하지 않았다. 나는 이것이 왜 일어나고 있는지에 대해 매우 혼란 스럽다.

답변

3

-removeFromSuperview을 호출하면 아무 것도 표시되지 않으면 해당보기가 할당 해제되므로 EXC_BAD_ACCESS이 표시됩니다. 할당 해제 된보기 (따라서 가비지를 가리키는 개체 포인터가 있음)가 나중에 -switchSubviews:withView에 전달되어 충돌을 일으킬 가능성이 큽니다.-removeFromSuperview을 호출하여 할당이 취소되지 않았는지 확인하기 전에 나중에 사용할보기를 항상 보유해야합니다.

편의상, -switchSubviews:withView:의 코드는 불필요하게 복잡합니다. 그것은 다음과 같이 줄일 수 있습니다 :

- (void)switchSubViews:(NSView *)firstView withView:(NSView *)secondView { 
    firstView.subviews = [NSArray array]; 
    [self prepareViews:firstView]; 
    [[firstView animator] addSubview:secondView]; 
} 
+0

감사합니다. 나는 그 자신을 알아 내지 못했을 것입니다. 그러나 나는 여전히 약간의 문제가있다. 프로젝트에서 ARC를 사용하는 경우 어떻게 뷰를 유지합니까? 보유 메시지를 명시 적으로 호출 할 수 없습니다. – ra1nmaster

+0

debugFromSuperview 코드를 주석 처리 한 후에도 오류가 지속되는 것으로 보입니다. 이것은 뷰의 할당이 해제되었음을 의미하지만 어디에서 찾을 수 없는지를 나타냅니다. 속성 (비 원자력, 강함)을 사용하여 뷰 속성을 설정 했으므로 뷰가 ARC에 의해 유지되어야한다는 의미가 아닙니까? – ra1nmaster

+0

firstView의 모든 하위 뷰를 유지해야합니까? 그렇다면 어떻게 할 수 있습니까? – ra1nmaster