2010-05-05 8 views
5

He estado caminando a través de un código de dos días tratando de averiguar por qué no se ha podido obtener una variable global NSMutableArray declaré en el .hy implementado en .m y situadas en una función de la viewDidLoad.¿Cómo se pasan objetos entre View Controllers en Objective-C?

Finalmente me di cuenta: no hay tal cosa como una variable global en Objective-C, al menos no en el sentido de PHP que hemos llegado a conocer. Yo no siempre realmente leído las advertencias de error XCode, pero allí estaba, aunque no del todo la llanura Inglés: "instancia de variable 'bla' accederse en el método de clase."

Mi pregunta: ¿Qué se supone que debo hacer ahora? Tengo dos controladores de vista que necesitan acceder a un NSMutableDictionary central que genero a partir de un archivo JSON a través de la URL. Se trata básicamente de un menú extendido por todos mis Tabla Ver bajadas de perforación, y me gustaría tener otras variables (no estáticos) par "globales".

¿Tengo que agarrar el JSON cada vez que quiero generar este NSMutableDictionary o hay alguna forma de configurarlo y acceder a él desde varias clases a través de #import? ¿Tengo que escribir datos en un archivo, o hay otra forma en que las personas usualmente hacen esto?

+1

"variable de instancia 'bla' accede en método de clase."indica un problema diferente: significa que tienes un método de clase (que comienza con" + ") que intenta hacer referencia a una variable de instancia. Como los métodos de clase, por definición, no están conectados a ninguna instancia particular de la clase, no lo hacen t tiene acceso a las variables de instancia. –

Respuesta

9

Si tiene dos controladores de vista que acceden al NSMutableDictionary compartido, puede pasar un puntero a el diccionario común en sus respectivos mensajes de inicio?

Así que en su AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // the app delegate doesn't keep a reference this, it just passes it to the 
    // view controllers who retain the data (and it goes away when both have been released) 
    NSMutableDictionary * commonData = [[NSMutableDictionary new] autorelease]; 

    // some method to parse the JSON and build the dictionary 
    [self populateDataFromJSON:commonData]; 

    // each view controller retains the pointer to NSMutableDictionary (and releases it on dealloc) 
    self.m_viewControllerOne = [[[UIViewControllerOne alloc] initWithData:commonData] autorelease]; 
    self.m_viewControllerTwo = [[[UIViewControllerTwo alloc] initWithData:commonData] autorelease]; 
} 

Y en sus respectivas implementaciones UIViewControllerOne y UIViewControllerTwo

- (id)initWithData:(NSMutableDictionary*)data 
{ 
    // call the base class ini 
    if (!(self=[super init])) 
     return nil; 

    // set your retained property 
    self.sharedData = data; 
} 

// don't forget to release the property 
- (void)dealloc { 
    [sharedData release]; 
    [super dealloc]; 
} 
+0

Interesante! No sabía que podía asignar una clase UIViewController con initWithData. He leído en un par de lugares que hacer esto en AppDelegate es un poco hackish. ¿Es eso malarky? – buley

+0

el mensaje initWithData no es un mensaje estándar en UIViewController. Es algo que deberás agregar a tus UIViewControllers para manejar la transferencia de datos (para que puedas agregar los parámetros que quieras a este mensaje). Enmendaré mi respuesta para aclarar. – RedBlueThing

+0

Gracias Estoy seguro de que esta es la mejor respuesta que obtendré. Todavía estoy tratando de entenderlo. Ojalá no te importe si hago algunas preguntas de seguimiento si son relevantes. – buley

1

hay variables globales en Obj-C, que ellos ejemplifican en la App Delegado.

Pero a su problema es probable que desee pasar el NSMutableDictonary cuando se instancia el nuevo controlador de vista como [UIView alloc] initWithDictionary: (NSMutableDictionary *) dict; Si sabes a lo que me refiero.

En su ejemplo ¿Le tienen una sola clase llamando a otra clase? Creo que hay algún tipo de controlador que determina qué controlador de visualización mostrar y ese sería el lugar para acceder y pasar el diccionario

1

Simplemente haga una variable global. Global significa fuera de cualquier ámbito.

NSMutableDictionary *gDictionary; 

@implementation ... 
@end 
+0

Eso sería increíble, pero no parece funcionar para mí. Seguiré intentando. – buley

2

Hay, de hecho, un montón de maneras que usted puede hacer esto (sin recurrir a algo extremo como escribir en un archivo). Se puede crear un "global" mediante el uso de:

  1. las variables pasadas de moda C globales (externs)
  2. A Singleton clase
  3. variables de instancia en el delegado de aplicaciones

Pero todos estos enfoques que su controlador de vista menos modular (porque dependen de llegar a "fuera" para encontrar los datos globales), por lo que el mejor enfoque es probablemente para hacer que el diccionario de una propiedad de la clase controlador de vista que se debe establecer explícitamente por la persona que llama (ya sea dentro de un initWithDictionary: m ethod, o con un setter separado).

+0

¿Qué es una clase singleton? (Perdón por mi ignorancia. Otra vez: sucio codificador PHP.) – buley

+0

Un "Singleton" es simplemente un nombre elegante para una clase que ejemplifica una sola instancia (voy a agregar un enlace a mi respuesta). Por ejemplo, puede tener una clase 'MySingleton' con un método de clase' sharedInstance' que devuelve esa instancia (única). A continuación, puede llamar a métodos en la instancia compartida como: '[[MySingleton sharedInstance] setFoo: @" foo "]' –

+0

Gracias, muy claro. Además, gracias por su comentario muy útil sobre mi pregunta original anterior. – buley

Cuestiones relacionadas