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
