3 preguntas sobre extern usadas en un proyecto de Objective-C

  1. Cuando uso la palabra extern antes de un método o statement de variable, ¿la hago global y, por lo tanto, legible / escribible / utilizable en todo el proyecto?

  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, ¿verdad? ¿Hay un equivalente en Objective-C? En realidad, no entiendo por qué usan una palabra clave C en un proyecto de Objective-C.

Gracias

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

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

 // 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 afecte la visibilidad (public / protected / private / package). para usar el símbolo (por ejemplo, la función constante o C), simplemente incluya el encabezado en el que está declarado.

algo confuso si eres nuevo en el lenguaje: colocando declaraciones C externas (constantes, funciones) entre @interface ... @end no alterará su scope:

 @interface MONClass : NSObject extern const size_t MaximumThreads; @end 

tiene el mismo scope (global) y visibilidad (público) que:

 @interface MONClass : NSObject @end extern const size_t MaximumThreads; 

así que realmente no tiene sentido colocar tus constantes C o funciones relacionadas con la clase en @interface...@end y @implementation...@end . Recomiendo ubicarlos en el mismo encabezado que la interfaz, fuera de @interface/@end y @implementation/@end y prefija el nombre con la clase a la que está asociado, así:

 @interface MONClass : NSObject @end extern const size_t MONClassMaximumThreads; // MONClass.m const size_t MONClassMaximumThreads = 23; 

y si quieres que esa constante sea privada, solo debes declararla y definirla así:

 // MONClass.m static const size_t MONClassMaximumThreads = 23; @implementation MONClass @end 

desafortunadamente, no existe una manera igualmente simple o común de hacer que esta constante esté protegida con objc.

finalmente, también puedes usar métodos de clase si el número varía de acuerdo a la 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 declarado 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, simplemente use un #define como este:

 #if !defined(__cplusplus) #define MONExternC extern #else #define MONExternC extern "C" #endif MONExternC const size_t MONClassMaximumThreads; 

extern no significa “global”, significa “definido en otra parte”. Se usa para indicarle al comstackdor 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 syntax y semántica. No hay construcción de C que se defina de otra manera en Objective-C.

Punto 3: Sí, puedes usar FOUNDATION_EXPORT en el objective C, que es una macro que se resuelve en una palabra clave diferente, dependiendo de si comstack C o C ++.

Más información aquí sobre las diferencias: “FOUNDATION_EXPORT” vs “extern”