2011-12-28 10 views
6

Estaba trabajando en un proyecto de Xcode y todo iba bien, hasta que dos de mis clases dejaron de reconocerse entre sí. He aquí un extracto:Las clases de Xcode no pueden "verse" entre ellas

#import "JBXViewController.h" 
@interface ViewController2 : UIViewController { 
    JBXViewController *jbx; 
} 

Por alguna razón, me sale el error "Desconocido nombre de tipo 'JBXViewController'; quiso decir 'UIViewController'?" No entiendo cómo esto es posible, ya que estoy importando la otra clase solo unas líneas arriba. ¡Cualquier idea sería muy apreciada!

+0

¿También está importando ViewController2.h en JBXViewController.h? –

+0

debe haber un problema sm con "JBXViewController.h". ¿Puedes publicar algún código inicial de la clase JBXViewController? – samfisher

+0

@FirozeLafeer: Estoy importando ViewController2.h en JBXViewController.h – Rob

Respuesta

11

Cuando dices que "no se pueden ver", supongo que quieres decir que también estás importando ViewController2.h en tu JBXViewController.h. Por lo que han encabezado una importación de otra cabecera, que importa la primera cabecera, que importa la segunda, que importa la primera vez ...

su lugar, utilice una referencia hacia adelante a JBXViewController:

@class JBXViewController; 

@interface ViewController2 : UIViewController { 
    JBXViewController *jbx; 
} 

Y luego #import "JBXViewController.h" en su implementación en su lugar (en su ViewController2.m)

5

La respuesta de Firoze Lafeer es correcta, pero este problema es probablemente un síntoma de diseño deficiente en su código.

Supongo que, en su aplicación, JBXViewController es un controlador de vista padre, y a veces muestra un ViewController2 para alguna función específica. (Por ejemplo, JBXViewController muestra una lista de registros, mientras que ViewController2 edita uno de los registros.) En una situación como esta, ViewController2 no debería conocer los detalles de JBXViewController. En su lugar, JBXViewController debe dar a ViewController2 los datos que necesita a través de las propiedades de ViewController2, y si ViewController2 tiene que llamar a los métodos en JBXViewController, deben ser parte de un protocolo de delegado.

Por ejemplo, supongamos que JBXViewController actualmente tiene la siguiente propiedad, y ViewController2 acceda a ella:

@property (strong) JBXObject * currentObject; 

su lugar, debe tener una propiedad currentObject en ViewController2 y JBXViewController debe configurarlo antes de mostrar el controlador de vista:

self.myViewController2.currentObject = self.currentObject; 
[self.navigationController pushViewController:self.myViewController2 animated:YES]; 

Esto funciona para comunicación unidireccional: JBXViewController puede proporcionar datos de ViewController2. Si los datos deben regresar a JBXViewController (a excepción de cambiar las propiedades de currentObject), debe configurar un delegado para ViewController2. Por ejemplo:

@protocol ViewController2Delegate; // forward declaration 
@interface ViewController2 : UIViewController 
@property (weak) id <ViewController2Delegate> delegate; 
... 
@end 

@protocol ViewController2Delegate <NSObject> 
- (void)viewController2ShouldSave:(ViewController2*)viewController2; 
- (BOOL)viewController2:(ViewController2*)viewController2 shouldAddSomoflange:(JBXSomoflange*)aSomoflange; 
@end 

Luego han JBXViewController cumplir con el protocolo:

@interface JBXViewController : UIViewController <ViewController2Delegate> 

Establecer el delegado, ya sea en el Interface Builder o en el código de este modo:

self.myViewController2.delegate = self; 
self.myViewController2.currentObject = self.currentObject; 
[self.navigationController pushViewController:self.myViewController2 animated:YES]; 

y poner en práctica toda la métodos listados en ViewController2Delegate.

En conjunto, estos cambios significan tres cosas:

  1. ViewController2 no necesita conocimientos específicos de cómo funciona JBXViewController. Esto significa que ya no tiene que importar JBXViewController.h en ViewController2.h, que resuelve tu problema inmediato.

  2. JBXViewController ahora es más flexible. Siempre que establezca las propiedades adecuadas en ViewController2 e implemente los métodos delegados necesarios, puede cambiar todo lo que desee en JBXViewController y ViewController2 nunca lo sabrá o le importará.

  3. ViewController2 ahora también es más flexible. Puede usarlo desde otras partes de la aplicación o moverlo a otra aplicación. Puede insertar una pantalla entre JBXViewController y ViewController2.

Estos cambios no son necesarios para que la aplicación se ejecute en su dispositivo y funcione de la manera que usted desea. Pero tendrás un tiempo más fácil en el futuro si comienzas a adoptar este tipo de diseños.

+0

Brent, sospecho que tienes razón. Gracias por la respuesta detallada y definitivamente voy a reconsiderar la forma en que se estructura el código. – Rob

Cuestiones relacionadas