Variabile di stringa statica in Objective C su iphone

Come creare e accedere alla stringa statica in iPhone (objective c)? Dichiara static NSString *str = @"OldValue" nella class A.

Se assegno un valore a questo in class B come str = @"NewValue" . Questo valore persiste per tutti i metodi della class B. Ma se accedo in class C (dopo l’assegnazione in B), lo sto ottenendo come OldValue. Mi sto perdendo qualcosa? Dovrei usare extern in altre classi?

Grazie e saluti, Yogini

Aggiornamento: A partire da Xcode 8, Objective-C ha proprietà di class. Nota, è principalmente zucchero sintattico; queste proprietà non sono auto-sintetizzate, quindi l’implementazione è sostanzialmente invariata rispetto a prima.

 // MyClass.h @interface MyClass : NSObject @property( class, copy ) NSString* str; @end // MyClass.m #import "MyClass.h" @implementation MyClass static NSString* str; + (NSString*) str { return str; } + (void) setStr:(NSString*)newStr { if( str != newStr ) { str = [newStr copy]; } } @end // Client code MyClass.str = @"Some String"; NSLog( @"%@", MyClass.str ); // "Some String" 

Vedi WWDC 2016 Novità di LLVM . La parte della proprietà di class inizia intorno al segno dei 5 minuti.

Risposta originale:

Objective-C non ha variabili di class, che è quello che penso tu stia cercando. Puoi farlo finta con variabili statiche, come stai facendo.

Ti consigliamo di inserire NSString statico nel file di implementazione della class e di fornire metodi di class per accedervi / mutarlo. Qualcosa come questo:

 // MyClass.h @interface MyClass : NSObject { } + (NSString*)str; + (void)setStr:(NSString*)newStr; @end // MyClass.m #import "MyClass.h" static NSString* str; @implementation MyClass + (NSString*)str { return str; } + (void)setStr:(NSString*)newStr { if (str != newStr) { [str release]; str = [newStr copy]; } } @end 

A differenza di Java, dove viene applicata una variabile statica per tutte le istanze di una class, static in C significa che una variabile è accessibile solo all’interno del file in cui è dichiarata. Ti permette di fare cose come dichiarare una variabile statica all’interno di una funzione, che imposta il valore solo la prima volta, in questo modo .

Una cosa che non hai menzionato è la relazione tra le classi A, B e C. Se sono in una gerarchia di ereditarietà e ti aspetti che la variabile statica venga ereditata come in Java, il metodo descritto da zpasternack funzionerà.

Se le tre classi non sono correlate e vuoi solo accedere al valore dichiarato in A, allora extern è un modo più appropriato per andare. In questo caso, si desidera dichiarare la variabile come extern in ClassA.h, quindi definirla in Class.m. Finché ClassB e ClassC importano ClassA.h, saranno in grado di collegarsi alla stessa definizione di extern.

Un punto è che, invece di usare extern da solo, è più robusto usare OBJC_EXPORT , che è definito in objc-api.h e gestisce anche la compilazione in C ++. Ecco un esempio di codice:

 // ClassA.h OBJC_EXPORT NSString* commonString; ... // ClassA.m NSString* commonString = @"OldValue"; // ClassB.m #import "ClassA.h" ... commonString = @"NewValue"; // Can be inside a function or method 

Ovviamente, l’uso di variabili esterne in questo modo crea una variabile globale infame e molto diffamatoria, che è fragile in quanto chiunque può leggerla o scriverla e l’accesso è incontrollato. Questo è l’approccio semplice e risponde alla tua domanda sull’uso di static rispetto a extern . Tuttavia, come principio di progettazione, l’incapsulamento fornito dal wrapping della variabile con i metodi di class è molto più sicuro, anche se più complesso. Nei linguaggi orientati agli oggetti, quando l’effetto che stai cercando di ottenere è quello di un metodo statico di class, l’incapsulamento è probabilmente la strada giusta da percorrere.