I want to be able to present a modal view with an instance of a UIViewController. I have no problem doing this when presenting it from a standard UIViewController (the root view). I have set up a delegate to make the presenting root view close the modal view. This is according to Apple best practice.
When I try to make the same root view present the modal view when the root view is loaded from a UITabBarController I get serious problems. The first three times I have no problem loading the view, but the fourth time the debugger shows that the the root view is deallocated when trying to call the delegate method ("message sent to deallocated instance"). My guess is that the root view has been autoreleased while the modal view was shown. How am I able to avoid this?
The example I have set up uses the template for the the UITabBarController, presenting the modal view from the first view:
FirstViewController.h (root view controller):
#import <UIKit/UIKit.h>
@protocol ModalDelegate;
@interface FirstViewController : UIViewController <ModalDelegate>{
}
-(IBAction)startPressed:(id)sender;
@end
FirstViewController.m:
#import "FirstViewController.h"
#import "ModalViewController.h"
@implementation FirstViewController
-(IBAction)startPressed:(id)sender
{
ModalViewController *modal=[[ModalViewController alloc] init];
modal.delegate=self;
[self presentModalViewController:modal animated:TRUE];
[modal release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[super dealloc];
}
#pragma mark Modal Delegate
-(void)modal:(ModalViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
@end
ModalViewController.h:
#import <UIKit/UIKit.h>
@protocol ModalDelegate;
@interface ModalViewController : UIViewController {
id<ModalDelegate> delegate;
}
@property (assign) id<ModalDelegate> delegate;
- (IBAction)OKPressed:(id)sender;
@end
@protocol ModalDelegate <NSObject>
@optional
-(void)modal:(ModalViewController *)controller;
@end
ModalViewController.m:
#import "ModalViewController.h"
@implementation ModalViewController
@synthesize delegate;
- (IBAction)OKPressed:(id)sender
{
if ([self.delegate respondsToSelector:@selector(modal:)]) //Check to see if method responds to selector
{
[self.delegate modal:self];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[delegate release];
[super dealloc];
}
@end