iphone - 平移手势导致 subview 崩溃?

标签 iphone objective-c ios xcode ipad

我使用初始 ViewController 创建一个项目作为单 View 应用程序;将 subViewController 添加到项目中。具有平移手势的 UIImageView 已添加到两个 View Controller 中。
它在 viewController.m 中工作, 但是当它添加到 subViewController 并将 subview 作为 subview 添加到 View Controller 时,程序就会因“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];

}

最佳答案

假设这是 ARC 代码,问题在于您正在创建 subview 的 View Controller ,获取其 View ,但随后让 Controller 本身超出范围并被释放。

立即的修复方法是使 SubViewController *sb 成为主视图 Controller 类的实例变量,这样它就不会超出范围,也不会在您后面释放。

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

因此,如果您要转换到新 View ,您确实应该通过 pushViewControllerpresentViewController 来完成。万一这确实是一个 subview (例如,前一个 View 的部分内容将保留在屏幕上,而 subview 将仅占用屏幕的一部分),您可以使用 View Controller Containment 。您可以看到WWDC 2011 session 102有关遏制的更多信息。但这对于你想做的事情来说无疑是多余的。推送/呈现 subview 可能是合乎逻辑的解决方案。

关于iphone - 平移手势导致 subview 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11372983/

相关文章:

iphone - Objective-C 中的 3DES 加密

Objective-c 中的 SQL 和 oop

objective-c - 转换与新 IOS 兼容的应用程序时出现弃用错误

iphone - View Controller 添加 subview

ios - 通过另一个 ObObject 传递 ObservableObject 模型?

iphone - 如何在点击时显示和隐藏按钮标题

iphone - glDrawArrays 在每一帧上分配内存

ios - UIWebView 检测 mp3 文件加载

iphone - 关闭屏幕播放声音/不要让 iPhone 进入休眠状态

ios - 使用原始类型 + 大小写参数的 Swift Enum 的解决方法?