Xcode中
好吧,我试图在Xcode中使用iPhone SDK中的简单UINavigationController,并且在推送时它工作得很好,但如果过了2推,并尝试弹出视图控制器,我一直收到错误:EXC_BAD_ACCESS
我知道这意味着什么,但是我怎么修复它?
这是我的代码...(假设MainViewController有一个调用showStartMenu函数的按钮)
FurballAppDelegate.h
// // FurballAppDelegate.h // Furball // // Created by Morgan Family on 7/28/10. // Copyright __MyCompanyName__ 2010. All rights reserved. // #import <UIKit/UIKit.h> @class MainViewController, StartViewController, SubjectViewController; @interface FurballAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; UINavigationController *navController; MainViewController *mainController; StartViewController *startController; } @property (nonatomic, retain) UIWindow *window; @property (nonatomic, retain) UINavigationController *navController; @property (nonatomic, retain) MainViewController *mainController; @property (nonatomic, retain) StartViewController *startController; - (void)popBack; - (void)pushNext:(UIViewController *)next; - (void)showStartMenu; @end
FurballAppDelegate.m
// // FurballAppDelegate.m // Furball // // Created by Morgan Family on 7/28/10. // Copyright __MyCompanyName__ 2010. All rights reserved. // #import "FurballAppDelegate.h" #import "MainViewController.h" #import "StartViewController.h" #import "SubjectViewController.h" @implementation FurballAppDelegate @synthesize window; @synthesize navController; @synthesize mainController; @synthesize startController; - (void)applicationDidFinishLaunching:(UIApplication *)application { window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; mainController = [[MainViewController alloc] init]; navController = [[UINavigationController alloc] initWithRootViewController:mainController]; [window addSubview:navController.view]; [window makeKeyAndVisible]; } - (void)dealloc { [mainController release]; [startController release]; [subjectController release]; [window release]; [super dealloc]; } - (void)popBack { [navController popViewControllerAnimated:YES]; } - (void)pushNext:(UIViewController *)next { [navController pushViewController:next animated:YES]; } - (void)showStartMenu { startController = [[StartViewController alloc] init]; [self pushNext:startController]; } @end
StartViewController.h
// // StartViewController.h // Furball // // Created by Morgan Family on 8/4/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import @interface StartViewController : UIViewController { } - (void)showSubjectMenu; @end
StartViewController.m
// // StartViewController.m // Furball // // Created by Morgan Family on 8/4/10. // Copyright 2010 __MyCompanyName__. All rights reserved. // #import "FurballAppDelegate.h" #import "StartViewController.h" #import "SubjectViewController.h" @implementation StartViewController - (void)loadView { UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btn setFrame:CGRectMake(50, 50, 100, 30)]; [btn setTitle:@"DO WORK" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(chooseSubject) forControlEvents:UIControlEventTouchUpInside]; [view addSubview:btn]; FurballAppDelegate *app = [[UIApplication sharedApplication] delegate]; UIButton *btnBack = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btnBack setFrame:CGRectMake(50, 100, 100, 30)]; [btnBack setTitle:@"DO WORK" forState:UIControlStateNormal]; [btnBack addTarget:app action:@selector(popBack) forControlEvents:UIControlEventTouchUpInside]; [view addSubview:btnBack]; self.view = view; [view release]; } - (void)viewDidLoad { [super viewDidLoad]; } - (void)chooseSubject { FurballAppDelegate *app = [[UIApplication sharedApplication] delegate]; SubjectViewController *subjectController = [[SubjectViewController alloc] init]; [app pushNext:subjectController]; } - (void)dealloc { [super dealloc]; } @end
所有的文件都可以工作。 即使是我触摸它时的“btnBack”,将导航控制器弹回到MainViewController ...但是当我使用与StartViewController上的后退按钮相同的按钮时,在SubjectViewController上它会给我那个奇怪的错误。
我真的很感激任何帮助:)
既然你意识到这意味着你试图访问一个无效的内存地址,你需要检查你的代码是否有无效的内存访问。
幸运的是,对于这个错误,它通常在您接收到EXEC_BAD_ACCESS的行上。 看看那条线上的对象和指针。 他们都有道理吗? 如果没有,请备份一行。 清洗,冲洗并重复。 某处你没有正确分配一个对象,过早释放它,堆栈损坏或者一些指向随机垃圾的变量。
在收到错误的地方发布一些代码可能会让我们发现错误。 但是,如果不能在调试器中单步执行,也是不可能看到的。
弹出视图控制器时获取EXEC_BAD_ACCESS会让我怀疑错误是在视图控制器的dealloc方法中触发的。 释放一个对象两次,或释放一个自动释放的对象?
我没有具体查明我在哪里遇到内存问题,但是我通过创建自己的导航控制器类来扩展UIViewController类,并使用其他方法,这对我使用的应用程序来说效果更好。 它使用很少的内存,但是通过类名记忆控制器,所以添加所有的UIViewControllers将不起作用。 但那不是我想要的。 我有许多视图控制器都有不同的类名,这工作得很好:)
FurballNavigationController.h
// // FurballNavigationController.h // Furball // #import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> @class UIViewController; @protocol FurballNavigationDelegate; @interface FurballNavigationController : UIViewController <FurballNavigationDelegate> { NSMutableArray *viewControllers; int currentController; UIViewController *pendingView; int pendingDirection; } @property (nonatomic, retain) NSMutableArray *viewControllers; @property (nonatomic) int currentController; - (id)initWithRootViewController:(UIViewController *)viewController; - (id)initWithViewControllers:(NSArray *)controllers; - (void)addObject:(id)object; - (void)removeObject:(unsigned int)index; - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)yesOrNo; - (UIViewController *)popViewControllerAnimated:(BOOL)yesOrNo; - (void)popToRootViewControllerAnimated:(BOOL)yesOrNo; - (void)animateSlide:(UIViewController *)viewController direction:(NSString * const)direction; @end @protocol FurballNavigationDelegate @optional - (void)viewFinishedAnimation; - (void)viewShouldPush:(UIViewController *)viewController; - (void)viewWillPush:(UIViewController *)viewController; - (void)viewDidPush:(UIViewController *)viewController; - (UIViewController *)viewShouldPopAnimated:(BOOL)yesOrNo; - (UIViewController *)viewWillPopAnimated:(BOOL)yesOrNo; - (UIViewController *)viewDidPopAnimated:(BOOL)yesOrNo; @end
FurballNavigationController.m
// // FurballNavigationController.m // Furball // #import "FurballNavigationController.h" @implementation FurballNavigationController @synthesize viewControllers; @synthesize currentController; - (id)init { NSMutableArray *arr = [[NSMutableArray alloc] init]; self.viewControllers = arr; [arr release]; currentController = 0; pendingView = nil; pendingDirection = 0; return self; } - (id)initWithRootViewController:(UIViewController *)viewController { if(self = [self init]) { if(viewController == nil) { viewController = [[UIViewController alloc] init]; viewController.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; [viewController.view setBackgroundColor:[UIColor redColor]]; } [self addObject:viewController]; self.view = viewController.view; } return self; } - (id)initWithViewControllers:(NSArray *)controllers { if(self = [self initWithViewControllers:[controllers objectAtIndex:0]]) { viewControllers = (NSMutableArray *)controllers; } return self; } - (void)addObject:(id)object { [viewControllers addObject:[NSString stringWithFormat:@"%@", [object class]]]; } - (void)removeObject:(unsigned int)index { [viewControllers removeObjectAtIndex:(NSInteger)index]; } - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)yesOrNo { pendingView = viewController; pendingDirection = 1; yesOrNo ? [self animateSlide:viewController direction:kCATransitionFromRight] : [self viewFinishedAnimation]; } - (UIViewController *)popViewControllerAnimated:(BOOL)yesOrNo { UIViewController *controller = [[NSClassFromString([viewControllers objectAtIndex:currentController-1]) alloc] init]; pendingView = controller; pendingDirection = -1; yesOrNo ? [self animateSlide:controller direction:kCATransitionFromLeft] : [self viewFinishedAnimation]; return controller; } - (void)popToRootViewControllerAnimated:(BOOL)yesOrNo { UIViewController *controller = [[NSClassFromString([viewControllers objectAtIndex:0]) alloc] init]; pendingView = controller; pendingDirection = -2; yesOrNo ? [self animateSlide:controller direction:kCATransitionFromLeft] : [self viewFinishedAnimation]; } - (void)animateSlide:(UIViewController *)viewController direction:(NSString * const)direction { UIView *currentView = self.view; UIView *theWindow = [currentView superview]; UIView *newView = viewController.view; [currentView removeFromSuperview]; [theWindow addSubview:newView]; CATransition *animation = [CATransition animation]; [animation setDuration:0.5]; [animation setType:kCATransitionPush]; [animation setSubtype:direction]; [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [[theWindow layer] addAnimation:animation forKey:@"SwitchToView1"]; NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(viewFinishedAnimation) userInfo:nil repeats:NO]; timer; } - (void)viewFinishedAnimation { self.view = pendingView.view; if(pendingDirection > 0) { [self addObject:pendingView]; currentController++; } else if(pendingDirection == -1) { [self removeObject:currentController]; currentController--; } else if(pendingDirection == -2) { for(int i = 1; i < [viewControllers count]; i++) [self removeObject:i]; currentController = 0; } } - (void)viewShouldPush:(UIViewController *)viewController { } - (void)viewWillPush:(UIViewController *)viewController { } - (void)viewDidPush:(UIViewController *)viewController { } - (UIViewController *)viewShouldPopAnimated:(BOOL)yesOrNo { return [[UIViewController alloc] init]; } - (UIViewController *)viewWillPopAnimated:(BOOL)yesOrNo { return [[UIViewController alloc] init]; } - (UIViewController *)viewDidPopAnimated:(BOOL)yesOrNo { return [[UIViewController alloc] init]; } @end
谢谢大家的帮助:D
链接地址: http://www.djcxy.com/p/74233.html上一篇: xcode