2011-09-07 4 views
22
  1. Cuando uso la palabra extern antes de un método o una declaración de variables, estoy haciendo lo global y, por tanto, lectura/escritura/utilizable durante todo el proyecto?3 preguntas sobre extern utilizados en un proyecto de Objective-C

  2. Si utilizo extern antes de una palabra clave, ¿hay alguna posibilidad de que todavía no sea accesible por parte de mi proyecto? Por ejemplo, solo por subclases ... como cuando uso "protegido".

  3. extern es una palabra clave C, ¿no? ¿Hay un equivalente en Objective-C? En realidad, no entiendo por qué usan una palabra clave C en un proyecto de Objective-C.

gracias

+3

Objective-C es un superconjunto de C. Entonces se aplican las palabras clave C. – Mat

+0

buena pregunta .. – Krishnabhadra

+0

@Mat Lo sé, pero mi punto era: ¿no es objetivo c proporcionar sus propias palabras clave para declarar los métodos y las variables globales? – aneuryzm

Respuesta

37

1) que está especificando su vinculación. El enlace externo le permite a usted o a cualquier cliente hacer referencia al símbolo.

con respecto a variables globales: si la variable es mutable y/o necesita una construcción adecuada, entonces debe considerar métodos o funciones para este objeto. la notable excepción a esto es NSString constantes:

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

2) no hay ningún caso en el que la palabra clave extern afecta a la visibilidad (/ protected/privada/pública paquete). para utilizar el símbolo (por ejemplo, la función constante o C), simplemente incluya el encabezado en el que está declarado.

algo confuso si es nuevo en el lenguaje: colocar declaraciones C externas (constantes, funciones) entre @interface ... @end no de alterar su alcance:

@interface MONClass : NSObject 

extern const size_t MaximumThreads; 

@end 

tiene el mismo alcance (global) y visibilidad (público) como:

@interface MONClass : NSObject 

@end 

extern const size_t MaximumThreads; 

por lo que realmente no tiene sentido para colocar sus relacionadas con la clase constantes o funciones de C en el @[email protected] y @[email protected]. te recomiendo estos puntos el mismo encabezado como la interfaz, fuera @interface/@end y @implementation/@end y anteponiendo el nombre de la clase que se asocia con, así:

@interface MONClass : NSObject 

@end 

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

y si quieres que la constante de estar privada, a declarar y definir así:

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

@implementation MONClass 

@end 

por desgracia, no hay manera igualmente simple o común para hacer esta constante protegido con objc.

por último, también se pueden utilizar métodos de la clase si el número debe variar por clase:

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

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

3) Sí, entre otros idiomas. por ejemplo, si usa extern const int Something en una traducción de C++, la traducción de C++ buscará Something declarada como un símbolo externo de C++. no hay sustitución en objc; objc es un superconjunto de C y hereda todas las funcionalidades de C. el uso de extern está bien formado y también puede encontrarlo en los marcos que usa (por ejemplo, Foundation). lo usan porque necesitan especificar un enlace. objc no ofrece un sustituto, presumiblemente porque no requiere un reemplazo o extensión.

Para evitar esto, sólo tiene que utilizar un #define así:

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

MONExternC const size_t MONClassMaximumThreads; 
+2

A un par de notas desde la perspectiva de las declaraciones de clase: wrt 1), no existe un método 'extern' en Objective-C; wrt 2), y relacionado con 1), no se aplica a las jerarquías de clase. –

+0

@Bavarious hmm ... no especifiqué que los métodos son externos, solo * exportados *. Voy a volver a leerlo mañana - estoy muy cansado atm. puede estar mal redactado :) siéntete libre de editarlo, si quieres. – justin

+0

Solo (¡con suerte!) Lo que es un poco más claro para el OP (y, después de 24 horas despierto, ni siquiera estoy considerando responder). –

16

extern no significa "global", que significa "definido en otro lugar". Se usa para indicarle al compilador que existe una variable o función (en otro archivo de objeto o biblioteca), de modo que no se queje y el vinculador se proporcionará con ese archivo de objeto o biblioteca. Como consecuencia, extern implica que el elemento de destino es global.

Objective-C es solo un superconjunto de C. Todo lo que está disponible en C está disponible también en Objective-C, con la misma sintaxis y semántica. No hay construcción de C que se defina de otra manera en Objective-C.

+0

Gracias. Entonces, ¿siempre tengo que importar el encabezado que contiene la declaración extern, si quiero usar el método/variable externo? – aneuryzm

+0

En otros términos, ¿puedo simplemente almacenar mis métodos/variables externos en una clase e importar su encabezado cuando necesito usarlos? Como alternativa, ¿no puede simplemente usar métodos estáticos o variables de un singleton? – aneuryzm

+1

'extern' no se aplica a métodos o variables de instancia, se aplica a funciones o variables fuera del alcance de una clase. – mouviciel

0

Punto 3: Sí, puedes usar FOUNDATION_EXPORT en C objetiva que es una macro que se resuelve en diferentes palabras clave en función de si la compilación de C o C++

Más información aquí en las diferencias: "FOUNDATION_EXPORT" vs "extern"