UITabBarController throws EXC_BAD_ACCESS
I create a tab bar controller in the app delegate. Here is the .h and .m file:
#import <UIKit/UIKit.h>
@interface appAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITabBarController *tabBar;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) UITabBarController *tabBar;
@end
here is the relevant function in the m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UINavigationController *localNav;
tabBar = [[UITabBarController alloc] init];
NSMutableArray *controllerArray = [[NSMutableArray alloc] initWithCapacity:2];
FirstViewController *firstViewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
localNav = [[UINavigationController alloc] initWithRootViewController:FirstViewController];
localNav.navigationBar.tintColor = [UIColor blackColor];
[controllerArray addObject:localNav];
[firstViewController release];
SecondViewController *secondViewController;
secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
localNav = [[UINavigationController alloc] initWithRootViewController:secondViewController];
[controllerArray addObject:localNav];
[localNav release];
[SecondViewController release];
tabBar.viewControllers = controllerArray;
[controllerArray release];
[localNav release];
[window addSubview:tabBar.view];
[self.window makeKeyAndVisible];
return YES;
}
I changed the variable names (ie the first view is not called first view controller). The app will load and show two tabs that I can choose between. The issue comes in when I try to show a modal popup. I have a button that when pressed should show the modal.
Here is the .h file. The custom button just rounds the corners of the button, other than that it is a straight extension of UIButton. The delegate just has functions for two buttons that are ok or cancel.:
#import <UIKit/UIKit.h>
#import "CustomButton.h"
#import "StartModal.h"
#import "CurrentEntry.h"
@interface FirstViewController : UIViewController <StartModalDelegate>{
CustomButton *startEntry;
}
@property (nonatomic, retain) IBOutlet CustomButton *startEntry;
- (IBAction) startLogEntry;
- (void) locationSelection;
- (void) dismissHandler;
- (void) saveHandler;
@end
The EXC_BAD_ACCESS comes in when I run the function for the button press. Here is th开发者_JAVA技巧e .m file:
- (IBAction) startLogEntry {
NSLog(@"start the entry here");
StartPoopModal *modal = [[StartModal alloc] initWithNibName:@"StartModal" bundle:nil];
[modal setDelegate:self];
UINavigationController *localNav;
localNav = [[UINavigationController alloc] initWithRootViewController:modal];
localNav.navigationBar.tintColor = [UIColor blackColor];
[self.tabBarController presentModalViewController:localNav animated:YES];
[modal release];
}
the [self.tabBarController presentModalViewController....] is what throws the error. This has worked in the past and for some reason it is throwing an error. As far as I know I haven't changed it. I don't have this in any form of version control so I cannot double check it.
First you did this.
localNav = [[UINavigationController alloc] initWithRootViewController:FirstViewController];
[controllerArray addObject:localNav];
then you did this. that's a leak right there. you didn't release local nav before giving it a new OWNED object.
localNav = [[UINavigationController alloc] initWithRootViewController:secondViewController];
[controllerArray addObject:localNav];
after that you did this
[localNav release];
then after awhile again, you called [localNav release] again.
and also, this line is suspicious
StartPoopModal *modal = [[StartModal alloc] initWithNibName:@"StartModal" bundle:nil];
you assigned two different classes
all i can say is check all the above bad programming and make sure to read memory management rules. http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
really helpful.
If the line
[self.tabBarController presentModalViewController:localNav animated:YES];
causes a bad access exception (EXC_BAD_ACCESS), then you should be looking for bad pointers. I see four pointers involved there: self
, self.tabBarController
, localNav
, and modal
.
I agree with @PatrickAnarna that the line where you allocate modal
is suspicious because the types don't match, but if StartModal
is a real class then that shouldn't cause the bad access exception. However, if modal
is nil, then you'd expect a bad access exception when the tab bar controller tries to access modal
's view. Or more specifically, when the tab bar controller tries to access localNav
's view, and localNav
in turn tries to access modal
's view.
I don't see how localNav
would be nil or invalid, but you should still check that. self
should never be nil in an instance method, and if self
is a view controller that's managed by a tab bar controllers, self.tabBarController
shouldn't be nil or invalid either. Again, though, you shouldn't assume that they're correct just because they're supposed to be -- after all the code is supposed to work, but it doesn't.
Anyway, at the end of the day, the error is caused by dereferencing a bad pointer. Find the pointer that's being dereferenced and you'll find your error.
精彩评论