2012-07-07 2 views
2

초기 ViewController가있는 단일보기 응용 프로그램으로 프로젝트를 만듭니다. 프로젝트에 subViewController를 추가하십시오. 팬 제스처가있는 UIImageView가 두 뷰 컨트롤러에 모두 추가됩니다.
그것은 viewController.m, 에서 작동하지만이 subViewController에 추가되고 서브 뷰는 뷰 컨트롤러에 하위 뷰를 같이 추가 될 때, 프로그램은 그냥 "EXC_BAD_ACCESS"로 충돌 ..팬 제스처가 하위보기에서 충돌을 일으 킵니까?

사람은 어떤 솔루션을? 여기

내 코드입니다 :

ViewController.m

#import "ViewController.h" 
#import "SubViewController.h" 

//#define SUB 

@interface ViewController() 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

#ifdef SUB 
    SubViewController *sb = [[SubViewController alloc] init]; 
    [self.view addSubview:sb.view]; 
#else 
    UIImageView* img_ = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"monkey_1.png"]]; 
    img_.userInteractionEnabled = YES; 
    UIPanGestureRecognizer *stampPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    [stampPanGesture setMinimumNumberOfTouches:1]; 
    [stampPanGesture setMaximumNumberOfTouches:1]; 
    [img_ addGestureRecognizer:stampPanGesture]; 
    img_.center = self.view.center; 
    [self.view addSubview:img_]; 
#endif 
} 


- (void)handlePan:(UIPanGestureRecognizer *)recognizer { 
    CGPoint translation = [recognizer translationInView:self.view]; 
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, 
             recognizer.view.center.y + translation.y); 
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view]; 

} 

SubViewController.m

#import "SubViewController.h" 
@interface SubViewController() 

@end 

@implementation SubViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 


    UIImageView* img_ = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"monkey_1.png"]]; 
    img_.userInteractionEnabled = YES; 
    UIPanGestureRecognizer *stampPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    [stampPanGesture setMinimumNumberOfTouches:1]; 
    [stampPanGesture setMaximumNumberOfTouches:1]; 
    [img_ addGestureRecognizer:stampPanGesture]; 
    img_.center = self.view.center; 
    [self.view addSubview:img_]; 
} 


- (void)handlePan:(UIPanGestureRecognizer *)recognizer { 
    CGPoint translation = [recognizer translationInView:self.view]; 
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, 
             recognizer.view.center.y + translation.y); 
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view]; 

} 

답변

2

이 ARC 코드 가정하면, 문제는 서브 뷰의 뷰 컨트롤러를 만드는 것입니다 , 그것의 전망을 움켜 잡는, 그러나 그 후에 관제사 자체는 범위에서 빠지고 할당 취소 될 것이다.

즉각적인 수정은 SubViewController *sb을 주 뷰 컨트롤러의 클래스의 인스턴스 변수로 만드는 것입니다. 그러면 범위를 벗어나서 할당 취소되지 않게됩니다.

문제는 실제로 충돌을 수정하지만 더 큰 문제는보기 컨트롤러의보기를 잡아서 하위보기로 추가하지 말고 컨트롤러 자체로는 아무 것도하지 않는 것입니다. 예를 들어, 다양한 일이 제대로 작동하지 않을 수 있습니다 (예 : 순환 이벤트가 하위보기에 도달하지 않을 수도 있습니다. iOS가 하위보기의 컨트롤러에서 컨트롤러를보기 위해 통신해야하는 모든 항목이 수신되지 않을 수 있습니다. 세계 didReceiveMemoryWarning 상황 등). 간단히 말해서, Apple은 이에 대해 조언하고 뷰 계층 구조와 뷰 컨트롤러 계층을 동기화 된 상태로 유지할 것을 권장합니다.

따라서 새로운보기로 전환하는 경우 실제로는 pushViewController 또는 presentViewController을 통해 전환해야합니다. 드물지만 이것이 실제로 하위보기 인 경우 (예 : 이전보기의 일부가 화면에 머무르고 하위보기가 화면의 일부만 차지함) View Controller Containment을 사용할 수 있습니다. 봉쇄에 대한 자세한 내용은 WWDC 2011 session 102을 참조하십시오. 하지만 그것은 의심 할 여지없이 당신이하려는 것을 과잉 살상입니다. 서브 뷰를 밀거나/선물하는 것은 아마도 논리적 인 해결책 일 것입니다.

관련 문제