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

下一篇: Rotating UIButtons on a view