2011-09-07 4 views
22
  1. Quando uso la parola extern prima di un metodo o una dichiarazione di variabile, sto facendo è globale e quindi leggibile/scrivibile/utilizzabile su tutto il progetto?3 domande su extern utilizzati in un progetto di Objective-C

  2. Se utilizzo extern prima di una parola chiave, è possibile che non sia ancora accessibile da parte del mio progetto? Ad esempio, solo per sottoclassi .. come quando uso "protetto".

  3. extern è una parola chiave C, giusto? Esiste un equivalente in Objective-C? In realtà non capisco perché usano una parola chiave C in un progetto Objective-C.

grazie

+3

Objective-C è un superset di C. Quindi si applicano le parole chiave C. – Mat

+0

buona domanda .. – Krishnabhadra

+0

@ Mat so, ma il mio punto era: non è obiettivo-c che fornisce le proprie parole chiave per dichiarare metodi e variabili globali? – aneuryzm

risposta

37

1) si sta specificando il suo collegamento. il collegamento esterno consente a te o a qualsiasi cliente di fare riferimento al simbolo.

relativo alle variabili globali: se la variabile è modificabile e/o richiede una costruzione corretta, è necessario considerare i metodi o le funzioni per questo oggetto. la notevole eccezione a questa è NSString costanti:

// MONClass.h 
extern NSString* const MONClassDidCompleteRenderNotification; 
// MONClass.m 
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification"; 

2) non v'è alcun caso in cui la parola chiave extern colpisce visibilità (/ protetto/privato/pubblico di pacchetti). per utilizzare il simbolo (ad esempio la costante o la funzione C), includere semplicemente l'intestazione in cui è dichiarato.

un po 'di confusione se si è nuovi alla lingua: posizionando dichiarazioni C esternamente (costanti, funzioni) tra @interface ... @end non sarà modificare il campo di applicazione:

@interface MONClass : NSObject 

extern const size_t MaximumThreads; 

@end 

ha la stessa portata (globale) e la visibilità (pubblico) come:

@interface MONClass : NSObject 

@end 

extern const size_t MaximumThreads; 

quindi ha davvero alcun senso mettere le costanti o funzioni C relative classe nel @[email protected] e @[email protected]. Mi raccomando mettendo questi nella stessa intestazione come l'interfaccia, al di fuori @interface/@end e @implementation/@end e anteponendo il nome con la classe cui è associato, in questo modo:

@interface MONClass : NSObject 

@end 

extern const size_t MONClassMaximumThreads; 
// MONClass.m 
const size_t MONClassMaximumThreads = 23; 

e se si vuole che continua ad essere privata, a soli dichiarare e definire in questo modo:

// MONClass.m 
static const size_t MONClassMaximumThreads = 23; 

@implementation MONClass 

@end 

purtroppo, non c'è modo altrettanto semplice o comune per rendere questo costante protetto con objc.

, infine, è anche possibile utilizzare i metodi della classe se il numero dovrebbe variare per classe:

@interface MONMammal : NSObject 
+ (NSUInteger)numberOfLegs; 
@end 

@implementation MONDog 
+ (NSUInteger)numberOfLegs { return 4; } 
@end 
@implementation MONHuman 
+ (NSUInteger)numberOfLegs { return 2; } 
@end 

3) Sì, tra le altre lingue. ad esempio, se si utilizza extern const int Something in una traduzione C++, la traduzione C++ cercherà lo Something dichiarato come simbolo C++ esterno. non vi è alcuna sostituzione in objc; objc è un superset di C ed eredita tutte le funzionalità di C. l'uso di extern è ben strutturato e puoi trovarlo anche nei framework che utilizzi (ad es. Foundation). lo usano perché devono specificare il collegamento. objc non offre un sostituto, presumibilmente perché non ha richiesto una sostituzione o un'estensione.

per evitare questo, è sufficiente utilizzare un #define come questo:

#if !defined(__cplusplus) 
#define MONExternC extern 
#else 
#define MONExternC extern "C" 
#endif 

MONExternC const size_t MONClassMaximumThreads; 
+2

A un paio di note dal punto di vista delle dichiarazioni di classe: wrt 1), non esiste un metodo 'extern' in Objective-C; wrt 2), e relativo a 1), non si applica alle gerarchie di classi. –

+0

@Bavarious hmm ... non ho specificato che i metodi siano esternamente, solo * esportati *. Lo rileggerò domani - sono piuttosto stanco. potrebbe semplicemente essere scritto male :) sentiti libero di modificarlo, se vuoi. – justin

+0

Solo (si spera!) Rendendolo un po 'più chiaro per l'OP (e, dopo 24 ore di risveglio, non sto nemmeno considerando di rispondere). –

16

extern non vuol dire "globale", che significa "definiti altrove". È usato per dire al compilatore che esiste una variabile o una funzione (in un altro file oggetto o libreria), in modo che non possa lamentarsi e che il linker sia fornito con quel file oggetto o libreria.

Di conseguenza extern implica che l'elemento di destinazione sia globale.

Objective-C è solo un superset di C. Tutto ciò che è disponibile in C è disponibile anche in Objective-C, con la stessa sintassi e semantica. Non esiste alcun costrutto di C che sia definito in un altro modo in Objective-C.

+0

Grazie. Quindi, devo sempre importare l'intestazione contenente l'istruzione extern, se voglio usare il metodo/variabile extern? – aneuryzm

+0

In altri termini, posso semplicemente memorizzare i miei metodi/variabili esterni in una classe e importarne l'intestazione quando devo usarli? Come alternativa non puoi semplicemente usare metodi o variabili statici da un singleton? – aneuryzm

+1

'extern' non si applica ai metodi o alle variabili di istanza, si applica a funzioni o variabili esterne all'ambito di una classe. – mouviciel

0

Punto 3: Sì, è possibile utilizzare FOUNDATION_EXPORT in Objective C, che è una macro che si risolve in diverse parole chiave a seconda se la compilazione di C o C++

Maggiori informazioni qui sulle differenze: "FOUNDATION_EXPORT" vs "extern"