EXC_BAD_ACCESS con iPhone SDK UINavigationController

De acuerdo, estoy tratando de usar un UINavigationController simple con iPhone SDK en Xcode y funciona bien al presionar, pero si pasa de 2 presiones e intento abrir los controladores de vista, sigo recibiendo el error: EXC_BAD_ACCESS

Sé lo que significa, pero ¿cómo diablos lo soluciono?

Aquí está mi código ... (Supongamos que MainViewController tiene un botón que invoca la función showStartMenu)

FurballAppDelegado.h

// // FurballAppDelegate.h // Furball // // Creado por Morgan Family el 7/28/10. // Copyright __MyCompanyName__ 2010. Todos los derechos reservados. // #importar @class MainViewController, StartViewController, SubjectViewController; @interface FurballAppDelegate: NSObject {UIWindow * ventana; UINavigationController * navController; MainViewController * mainController; StartViewController * startController; } @property (no atómico, conservar) UIWindow * ventana; @property (no atómico, retener) UINavigationController * navController; @property (no atómico, retener) MainViewController * mainController; @property (no atómico, retener) StartViewController * startController; - (anulado) popBack; - (void) pushNext: (UIViewController *) siguiente; - (vacío) showStartMenu; @final

FurballAppDelegado.m

// // FurballAppDelegate.m // Furball // // Creado por Morgan Family el 7/28/10. // Copyright __MyCompanyName__ 2010. Todos los derechos reservados. // #importar "FurballAppDelegate.h" #importar "MainViewController.h" #importar "StartViewController.h" #importar "SubjectViewController.h" @implementation FurballAppDelegate @synthesize window; @synthesize navController; @synthesize mainController; @synthesize startController; - (void) applicationDidFinishLaunching: (UIApplication *) application {window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] límites]]; mainController = [[MainViewController alloc] init]; navController = [[UINavigationController alloc] initWithRootViewController: mainController]; [ventana addSubview: navController.view]; [ventana makeKeyAndVisible]; } - (void) dealloc {[versión de mainController]; [lanzamiento de startController]; [lanzamiento de subjectController]; [liberación de la ventana]; [super desalloc]; } - (void) popBack {[navController popViewControllerAnimated: SÍ]; } - (void) pushNext: (UIViewController *) next {[navController pushViewController: siguiente animado: SÍ]; } - (void) showStartMenu {startController = [[StartViewController alloc] init]; [auto pushNext: startController]; } @final

StartViewController.h

// // StartViewController.h // Furball // // Creado por Morgan Family el 8/4/10. // Copyright 2010 __MyCompanyName__. Reservados todos los derechos. // #importar @interface StartViewController: UIViewController {} - (void) showSubjectMenu; @final

StartViewController.m

// // StartViewController.m // Furball // // Creado por Morgan Family el 8/4/10. // Copyright 2010 __MyCompanyName__. Reservados todos los derechos. // #importar "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: autoacción: @selector (chooseSubject) forControlEvents: UIControlEventTouchUpInside]; [ver addSubview: btn]; FurballAppDelegate * app = [[UIApplication sharedApplication] delegado]; UIButton * btnBack = [UIButton buttonWithType: UIButtonTypeRoundedRect]; [btnBack setFrame: CGRectMake (50, 100, 100, 30)]; [btnBack setTitle: @ "DO WORK" forState: UIControlStateNormal]; [btnBack addTarget: acción de la aplicación: @selector (popBack) forControlEvents: UIControlEventTouchUpInside]; [ver addSubview: btnBack]; self.view = ver; [ver comunicado]; } - (void) viewDidLoad {[super viewDidLoad]; } - (void) chooseSubject {FurballAppDelegate * app = [[UIApplication sharedApplication] delegado]; SubjectViewController * subjectController = [[SubjectViewController alloc] init]; [app pushNext: subjectController]; } - (vacío) dealloc {[super dealloc]; } @final

Todo el trabajo de empujar en todos mis archivos. Incluso el "btnBack" cuando lo toco, hace que el controlador de navegación vuelva a MainViewController ... pero cuando hago un botón de retroceso idéntico al de StartViewController, en el SubjectViewController me da ese extraño error.

Realmente aprecio cualquier ayuda :)

preguntado el 13 de agosto de 10 a las 13:08

3 Respuestas

Dado que se da cuenta de que significa que está intentando acceder a una dirección de memoria no válida, debe examinar su código en busca de accesos de memoria no válidos.

Afortunadamente, para este error, normalmente está justo en la línea donde recibe EXEC_BAD_ACCESS. Mire los objetos y punteros en esa línea. ¿Tienen sentido todos? Si no es así, retroceda una línea. Lavar, aclarar y repetir. En algún lugar no está asignando un objeto correctamente, lo está liberando demasiado pronto, tiene una pila corrupta o alguna variable que apunta a basura aleatoria.

Publicar parte del código en el lugar donde recibe el error puede permitirnos detectar el error. Sin embargo, también es posible que sea imposible de ver sin poder realizar un solo paso en el depurador.

Respondido 13 ago 10, 17:08

Obtener EXEC_BAD_ACCESS al abrir un controlador de vista me haría sospechar que el error se activa en un método dealloc en un controlador de vista. ¿Liberar un objeto dos veces o liberar un objeto liberado automáticamente?

Respondido 13 ago 10, 20:08

No descubrí específicamente dónde estaba teniendo el problema de memoria, pero usé un método alternativo al crear mi propia clase de controlador de navegación que extendió la clase UIViewController y funciona mucho mejor para la aplicación que estoy usando. Utiliza muy poca memoria pero memoriza los controladores por su nombre de clase, por lo que agregar todos los UIViewControllers no funcionaría. Pero eso no es lo que quiero. Tengo muchos controladores de vista, todos con un nombre de clase diferente y esto funciona bien :)

FurballNavigationController.h

// // FurballNavigationController.h // Furball // #importar #importar @class UIViewController; @protocol FurballNavigationDelegate; @interface FurballNavigationController: UIViewController {NSMutableArray * viewControllers; int currentController; UIViewController * pendienteView; int pendienteDirección; } @property (no atómico, retener) NSMutableArray * viewControllers; @property (nonatomic) int currentController; - (id) initWithRootViewController: (UIViewController *) viewController; - (id) initWithViewControllers: (NSArray *) controladores; - (void) addObject: (id) objeto; - (void) removeObject: (unsigned int) índice; - (void) pushViewController: (UIViewController *) viewController animado: (BOOL) yesOrNo; - (UIViewController *) popViewControllerAnimated: (BOOL) yesOrNo; - (void) popToRootViewControllerAnimated: (BOOL) yesOrNo; - (void) animateSlide: (UIViewController *) viewController dirección: (NSString * const) dirección; @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; @final

FurballNavigationController.m

// // FurballNavigationController.m // Furball // #importar "FurballNavigationController.h" @implementation FurballNavigationController @synthesize viewControllers; @synthesize currentController; - (id) init {NSMutableArray * arr = [[NSMutableArray alloc] init]; self.viewControllers = arr; [arr release]; currentController = 0; pendienteView = nil; pendienteDirección = 0; volver a sí mismo; } - (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 *) controladores {if (self = [self initWithViewControllers: [controladores objectAtIndex: 0]]) {viewControllers = (NSMutableArray *) controladores; } return self; } - (void) addObject: (id) objeto {[viewControllers addObject: [NSString stringWithFormat: @ "% @", [clase de objeto]]]; } - (void) removeObject: (unsigned int) index {[viewControllers removeObjectAtIndex: (NSInteger) index]; } - (void) pushViewController: (UIViewController *) viewController animado: (BOOL) yesOrNo {pendienteView = viewController; pendienteDirección = 1; sí o no ?  [self animateSlide: viewController dirección: kCATransitionFromRight]: [self viewFinishedAnimation]; } - (UIViewController *) popViewControllerAnimated: (BOOL) yesOrNo {UIViewController * controller = [[NSClassFromString ([viewControllers objectAtIndex: currentController-1]) alloc] init]; pendienteView = controlador; pendienteDirección = -1; sí o no ?  [self animateSlide: dirección del controlador: kCATransitionFromLeft]: [self viewFinishedAnimation]; controlador de retorno; } - (void) popToRootViewControllerAnimated: (BOOL) yesOrNo {UIViewController * controller = [[NSClassFromString ([viewControllers objectAtIndex: 0]) alloc] init]; pendienteView = controlador; pendienteDirección = -2; sí o no ? 

Gracias por la ayuda de todos los demás: D

Respondido 15 ago 10, 18:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.