泛手势导致子视图崩溃?

时间:2012-07-07 06:58:25

标签: iphone objective-c ios xcode ipad

我使用初始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];

}

1 个答案:

答案 0 :(得分:2)

假设这是ARC代码,问题是你正在创建子视图的视图控制器,抓住它的视图,但是让控制器本身超出范围并被释放。

立即修复将使SubViewController *sb成为主视图控制器类的实例变量,这样它就不会超出范围而不会在你后面解除分配。

事情是,虽然这可能会解决你的崩溃,但更大的问题是你真的不应该抓住视图控制器的视图并将其添加为子视图,而是对控制器本身不采取任何措施。例如,如果您这样做,各种事情可能无法正常工作(例如,旋转事件永远不会到达您的子视图; iOS需要与视图控制器通信的任何内容可能都不会被子视图的控制器接收;我不知道世界didReceiveMemoryWarning情况会发生,等等。简而言之,Apple建议不要这样做,并鼓励您保持视图层次结构和视图控制器层次结构同步。

因此,如果您要转换到新视图,那么您应该通过pushViewControllerpresentViewController进行转换。万一这实际上是一个子视图(例如,先前视图的部分将保留在屏幕上,子视图将只占用屏幕的一部分),您可以使用View Controller Containment。有关收容的更多信息,请参阅WWDC 2011 session 102。但这对于你正在尝试做的事情来说无疑是过度杀伤力。推送/展示子视图可能是合乎逻辑的解决方案。