2

我使用初始 ViewController 创建了一个作为单视图应用程序的项目;将 subViewController 添加到项目中。在两个视图控制器中都添加了带有平移手势的 UIImageView。
它在 viewController.m 中工作,但是当它被添加到 subViewController 并且子视图作为子视图添加到视图控制器中时,程序会因“Exc_bad_access”而崩溃。

任何人都有一些解决方案?

这是我的代码:

视图控制器.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];

}

子视图控制器.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];

}
4

1 回答 1

2

假设这是 ARC 代码,问题是您正在创建子视图的视图控制器,获取它的视图,然后让控制器本身超出范围并被释放。

直接的解决方法是创建SubViewController *sb主视图控制器类的实例变量,这样它就不会超出范围,也不会在你身后被释放。

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

因此,如果您要转换到新视图,您真的应该通过pushViewControlleror来完成presentViewController。万一这真的是一个子视图(例如,先前视图的一部分将保留在屏幕上,而子视图将只占据屏幕的一部分),您可以使用View Controller Containment。您可以查看WWDC 2011 会议 102了解有关遏制的更多信息。但这对于您正在尝试做的事情来说无疑是矫枉过正。推送/呈现子视图可能是合乎逻辑的解决方案。

于 2012-07-07T07:13:42.573 回答