Reputation: 305
I am having a really hard time getting this to work. I have two view controllers with associated views called DomainSelectionViewController and DomainViewController. I'm going through a tutorial on Apple's developer network that covers presenting view controllers. I'm getting an EXC_BAD_ACCESS signal when trying to run.
Here are the relevant excerpts from each file:
DomainSelectionViewController.h
@class DomainViewController;
@interface DomainSelectionViewController : UIViewController
- (IBAction)domainSelected:(id)sender;
- (IBAction)leaveDomain;
@property (retain) DomainViewController * selectedDomain;
@end
domainSelected: is attached to a button that represents a domain. Clicking on it successfully replaces the current view in the interface with the view defined in DomainViewController's 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.");
}
}
The domainview contains only one button that reads "back" and is connected to its own exit: function, which in turn calls leaveDomain on its delegate. It is on clicking on this button that the EXC_BAD_ACCESS call arises. Looking at other similar posts, it's said that the EXC_BAD_ACCESS error typically arises from trying to call upon a deallocated object, but the print statement just before the dismiss call shows that the objects are still there and can be referred to. I was hoping someone with more experience than I could look at this and easily divine what has gone wrong.
For completeness's sake, here's the output from the console:
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)
Upvotes: 0
Views: 2585
Reputation: 305
So after quite a bit of trial-and-error, the issue here was higher up in the view hierarchy. The design had a root view controller that was completely empty, which replaced its own view with the first (DomainSelectionViewController) controller's view
self.window.rootViewController.view = domainSelectionViewController.view;
The end result of which is that domainSelectionViewController could present domainViewController's view, but trying to dismiss it resulted in EXC_BAD_ACCESS. I'm still not entirely sure why, but changing it such that domainSelectionViewController was the primary view, or having rootViewController present domainSelectionViewController in ViewDidAppear fixed the issue.
Upvotes: 1
Reputation: 25372
Oh, well there's your problem.
You are calling the function:
[self dismissViewControllerAnimated:NO completion:nil];
This is the function that should be incorporated in the new view controller that you are trying to display, not in the original view, as you are trying to destroy the root view.
Instead, do this:
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.");
}
}
This way, you get rid of the view controller you are presenting. Using self.presentingViewController will not work either because the parent view controller is the one you want to dismiss in order to see the selection view beneath it; dismissing the presented controller will leave you with a white screen.
Hope this helps you and good luck!
Upvotes: 0