2009-08-08 15 views

risposta

26

Ci sono un paio di modi diversi si può fare questo:

  1. Invece di dichiarare come una variabile globale, avvolgerlo in un oggetto Singleton, allora hanno il singleton da disponibile ovunque (da #importing la .h file)

  2. Creare un file .h, come "Globals.h". Nel .h, dichiarare la matrice come extern NSMutableArray * myGlobalArray; Poi nel qualche altra parte nel vostro app (l'AppDelegate è un buon posto), basta fare: myGlobalArray = [[NSMutableArray alloc] init]; Allora ovunque sia necessario l'array, basta #import "Globals.h"

  3. Questo è come # 2 , ma senza l'intestazione globale. È possibile definire l'array come extern NSMutableArray *myGlobalArray; all'interno del blocco #ifdef __OBJC__ del file .pch del progetto. Il file .pch è un file di intestazione che viene automaticamente # importato in ogni file del progetto.

Ci sono pro e contro di ciascun approccio. Ho usato tutti e tre in momenti diversi in circostanze diverse. Direi che l'approccio Singleton è probabilmente il più appropriato, dal momento che sarebbe più flessibile per l'inizializzazione, la restrizione dell'accesso e la gestione della memoria. Tuttavia, può non essere necessario se non ne hai bisogno.

L'opzione # 2 è utile se si dispone di molte variabili "globali" che non si desidera esporre a tutti i file del progetto. Puoi solo #importarlo dove è necessario. Tuttavia, questo approccio (così come il # 3) dissocia la dichiarazione dall'inizializzazione (cioè l'oggetto non è creato vicino a dove è stato dichiarato). Alcuni potrebbero obiettare che questo non è corretto e potrebbero essere corretti.

L'opzione n. 3 è piacevole perché non devi mai ricordare di #importare nulla. Tuttavia, solleva le stesse domande dell'opzione # 2.

+0

Ciao io ho usato la terza opzione, ma quando uso ** extern statico NSMutableArray * myGlobalA rray; ** dà un errore di ** Multiple classi di memoria nello specificatore di dichiarazione ** – rptwsthi

+1

@rptwsthi yeah sorry. Basta rimuovere il bit "statico". –

+0

l'ultima volta non sono riuscito a ottenere la risposta desiderata dalla terza via, ma questa volta l'ho fatto. Grazie per questo bel post. :) – rptwsthi

8

Una quarta risposta è quella di dichiarare la matrice nella vostra UIApplicationDelegate e accedervi tramite

[[[UIApplication sharedApplication] delegate] myArray]; 

Per momenti in cui ho solo bisogno di una manciata di oggetti globali, ho trovato questo è il modo più semplice e più pulito per farlo .

+6

+1 Questo è anche un buon approccio. L'unica avvertenza è che produrrà un avvertimento del compilatore, poiché - [delegato UIApplication] restituisce un oggetto di tipo id , che non ha un metodo "myArray". La soluzione sarebbe quella di lanciarlo, ma ciò rende la linea un po 'più difficile da preparare: '[(MyAppDelegate *) [[UIApplication sharedApplication] delegate] myArray];' –

+1

Inoltre, lanciare significa che è necessario anche # importare il File di intestazione MyAppDelegate. –

+0

Io uso Xcode 4.3. La situazione che hai menzionato costringerà un errore, non solo un avvertimento. – Philip007

2

Se state pensando di memorizzazione di un qualche tipo di preferenze condivise per la vostra applicazione, usare [NSUserDefaults sharedDefaults] per salvare i dati semplice che può essere utilizzato in tutta app. Se stai memorizzando dati transitori, allora l'approccio 'statico' funzionerà come altrove.

Tuttavia è probabilmente preferibile utilizzare un approccio a oggetti singleton con un accesso di classe, come NSUserDefaults, e quindi fornire metodi di accesso all'istanza per acquisire i dati. In questo modo, ti isolerai da potenziali modifiche alla struttura dei dati in futuro. Dovresti quindi usare una var statica, come sopra, ma all'interno del file .m (e quindi non hai bisogno della definizione 'extern'). Sarebbe tipicamente simile:

static Foo *myDefault = nil; 
@implementation Foo 
+(Foo)defaultFoo { 
    if(!myDefault) 
    myDefault = [[Foo alloc] init]; // effective memory leak 
    return myDefault; 
} 
@end 

Farebbe quindi le funzioni di accesso istanza, e li usa come [[Foo defaultFoo] myArray] cui si può accedere da qualsiasi parte della app, e senza errori in fase di compilazione.

1

Tutti qui sembrano avere una prima linea implicita e omessa: "Puoi farlo K & R C-style, o ..."

Sì, è ancora possibile farlo in stile C

Nel file di 1:.

NSArray *MyArray; 

Nel file di 2:.

extern NSArray *MyArray; 

Giocando Capitan Ovvio qui

+1

Non è così ovvio, penso che sia abbastanza comune per i nuovi sviluppatori Obj-C non avere esperienza C. – kubi

1

In riferimento alla risposta di Dave qui:

Questo è come il n. 2, ma senza l'intestazione globale. È possibile definire la matrice come extern statico NSMutableArray * myGlobalArray; all'interno del blocco #ifdef OBJC del file .pch del progetto. Il file .pch è un file di intestazione che viene automaticamente # importato in ogni file del progetto.

typedef è una classe di memoria e static è una classe di memoria e si possono definire solo oggetti in una classe di memoria. Estrarre "statico" permetterà all'app di compilare la tua risposta sopra.

0

Ci sono diverse possibilità. I più popolari:

1 Utilizzare Singleton oggetto - http://www.galloway.me.uk/tutorials/singleton-classes/

2 dichiararla in App delegato:

@interface Your_App_Delegate : UIResponder <UIApplicationDelegate> 

@property (nonatomic, strong) NSArray *array; 
    . . . 

e accedervi:

((Your_App_Delegate*)[[UIApplication sharedApplication] delegate]).array; 

3 Usa NSUserDefault