调用dismissViewControllerAnimated时出现EXC_BAD_ACCESS错误:完成:(iOS5)

时间:2012-03-24 23:41:39

标签: objective-c xcode cocoa ios5 viewcontroller

我很难让这个工作。我有两个视图控制器与相关的视图称为DomainSelectionViewController和DomainViewController。我正在浏览Apple开发人员网络上的一个教程,该教程涵盖视图控制器。尝试运行时,我收到一个EXC_BAD_ACCESS信号。

以下是每个文件的相关摘录:

DomainSelectionViewController.h

@class DomainViewController;

@interface DomainSelectionViewController : UIViewController

- (IBAction)domainSelected:(id)sender;
- (IBAction)leaveDomain;

@property (retain) DomainViewController * selectedDomain;

@end

domainSelected:附加到代表域的按钮。单击它可以使用DomainViewController的nib中定义的视图替换接口中的当前视图。

DomainSelectionViewController.m

@implementation
- (IBAction)domainSelected:(id)sender {
    NSLog(@"Domain Selected...");
    selectedDomain = [[DomainViewController alloc] initWithNibName:@"DomainView" bundle:nil];
    selectedDomain.domainSelectionContext = self;
    [self presentViewController:selectedDomain animated:NO completion:nil];
}

- (IBAction)leaveDomain {
    NSLog(@"Leaving Domain...");
    NSLog(@"Presented Domain: %@", self.presentedViewController);
    //selectedDomain.modalPresentationStyle = UIModalPresentationFullScreen;
    [self dismissViewControllerAnimated:NO completion:nil];
}

DomainViewController.h

#import <UIKit/UIKit.h>
#import "DomainSelectionViewController.h"

@class DomainSelectionViewController;

@interface DomainViewController : UIViewController

//@property (nonatomic, assign) DomainSelectionViewController * presentingViewController;
@property (nonatomic, retain) DomainSelectionViewController * domainSelectionContext;

@end

DomainViewController.m

- (IBAction)exit:(id)sender {
    NSLog(@"Leaving Domain...");
    if(self.presentingViewController) {
        NSLog(@"  Dismissing View Controller: %@.", self.presentingViewController);
        [self.domainSelectionContext leaveDomain];
        //[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
        return;
    }
    else {
        NSLog(@"Presenting view controller not set.");
    }
}

域视图只包含一个“后退”按钮并连接到自己的exit:function,后者又在其委托上调用leaveDomain。单击此按钮时会出现EXC_BAD_ACCESS调用。查看其他类似的帖子,据说EXC_BAD_ACCESS错误通常来自于尝试调用已释放的对象,但是在解除调用之前的print语句显示对象仍然存在并且可以被引用。我希望有更多经验的人比我能看到这一点,并且很容易理解出错的地方。

为了完整起见,这是控制台的输出:

Attaching to process 26860.
2012-03-24 19:23:45.601 domaintest[26860:f803] DomainSelectionView Initialized.
2012-03-24 19:23:52.627 domaintest[26860:f803] Domain Selected...
2012-03-24 19:24:14.187 domaintest[26860:f803] Leaving Domain...
2012-03-24 19:24:14.188 domaintest[26860:f803]   Dismissing View Controller: <DomainSelectionViewController: 0x688f9a0>.
2012-03-24 19:24:14.188 domaintest[26860:f803] Leaving Domain...
2012-03-24 19:24:14.188 domaintest[26860:f803] Presented Domain: <DomainViewController: 0x6891d90>
Current language:  auto; currently objective-c
warning: Attempting to create USE_BLOCK_IN_FRAME variable with block that isn't in the frame.
(gdb)

2 个答案:

答案 0 :(得分:1)

因此,在经过相当多的反复试验后,此处的问题在视图层次结构中更高。该设计有一个完全为空的根视图控制器,它用第一个(DomainSelectionViewController)控制器的视图替换了它自己的视图

self.window.rootViewController.view = domainSelectionViewController.view;

最终结果是domainSelectionViewController可以呈现domainViewController的视图,但是尝试关闭它会导致EXC_BAD_ACCESS。我仍然不完全确定原因,但更改它使得domainSelectionViewController是主视图,或者在ViewDidAppear中使用rootViewController present domainSelectionViewController解决了这个问题。

答案 1 :(得分:0)

哦,这是你的问题。

您正在调用该函数:

[self dismissViewControllerAnimated:NO completion:nil];

这个函数应该包含在您尝试显示的新视图控制器中,而不是原始视图中,因为您试图销毁 root 视图。

相反,这样做:

<强> DomainSelectionViewController.m

- (IBAction)leaveDomain {
    NSLog(@"Leaving Domain...");
    NSLog(@"Presented Domain: %@", self.presentedViewController);
    //selectedDomain.modalPresentationStyle = UIModalPresentationFullScreen;
}

<强> DomainViewController.m

- (IBAction)exit:(id)sender {
    NSLog(@"Leaving Domain...");
    if(self.presentingViewController) {
        NSLog(@"  Dismissing View Controller: %@.", self.presentingViewController);
        [self.domainSelectionContext leaveDomain];
        //ADD THIS HERE
        [self dismissViewControllerAnimated:NO completion:nil];

        return;
    }
    else {
        NSLog(@"Presenting view controller not set.");
    }

}

这样,您就可以摆脱正在呈现的视图控制器。使用self.presentingViewController将无法工作,因为父视图控制器是您要关闭的视图控制器,以便查看它下面的选择视图;解雇所提供的控制器将为您留下白屏。

希望这能帮助你,祝你好运!

相关问题