3 preguntas sobre el uso externo en un proyecto Objective-C

6 minutos de lectura

avatar de usuario
aneurisma

  1. Cuando uso la palabra extern antes de una declaración de método o variable, ¿lo estoy haciendo global y, por lo tanto, legible/escribible/utilizable en todo el proyecto?

  2. Si uso extern antes de una palabra clave, ¿hay alguna posibilidad de que parte de mi proyecto aún no pueda acceder a ella? Por ejemplo, solo por subclases… como cuando uso “protegido”.

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

Gracias

  • Objective-C es un superconjunto de C. Por lo tanto, se aplican las palabras clave de C.

    – Estera

    7 de septiembre de 2011 a las 7:07

  • @Mat Lo sé, pero mi punto era: ¿objetivo-c no proporciona sus propias palabras clave para declarar métodos y variables globales?

    – aneurisma

    7 de septiembre de 2011 a las 7:15

  • @Patrick: lo que quise decir es que “extern es la palabra clave C, ¿verdad? ¿Hay un equivalente en Objective C?” realmente no tiene sentido. El Objective-C equivalente a la C extern es… extern. Ver también Uso de extern en Objective C (y las 4 o 5 preguntas principales relacionadas en esta página)

    – Estera

    7 de septiembre de 2011 a las 7:18


avatar de usuario
justin

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 debe considerar métodos o funciones para este objeto. la notable excepción 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 externa afecte la visibilidad (público/protegido/privado/paquete). para usar el símbolo (por ejemplo, la función constante o C), simplemente incluya el encabezado en el que se declara.

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

@interface MONClass : NSObject

extern const size_t MaximumThreads;

@end

tiene el mismo alcance (global) y visibilidad (pública) que:

@interface MONClass : NSObject

@end

extern const size_t MaximumThreads;

por lo que realmente no tiene sentido colocar sus constantes o funciones C relacionadas con la clase en el @interface...@end y @implementation...@end. Recomiendo colocarlos en el mismo encabezado que la interfaz, fuera @interface/@end y @implementation/@end y prefijando 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 desea que esa constante sea privada, simplemente declare y defínala así:

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

@implementation MONClass

@end

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

finalmente, también puede usar métodos de clase si el número debe variar según 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 usas extern const int Something en una traducción de C++, la traducción de C++ buscará Something declarado como un símbolo C++ externo. no hay sustitución en objc; objc es un superconjunto de C y hereda todas las funcionalidades de C. uso de extern está bien formado y también puede encontrarlo en los marcos que utiliza (por ejemplo, Foundation). lo usan porque necesitan especificar la vinculación. objc no ofrece un sustituto, presumiblemente porque no requirió un reemplazo o extensión.

para evitar esto, simplemente use un #define Me gusta esto:

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

MONExternC const size_t MONClassMaximumThreads;

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

    usuario557219

    7 de septiembre de 2011 a las 7:23


  • @Bavarious hmm… no especifiqué que los métodos son externos, solo exportado. Lo volveré a leer mañana. Estoy bastante cansado. puede que esté mal redactado 🙂 siéntase libre de editarlo, si lo desea.

    – Justin

    7 de septiembre de 2011 a las 7:53

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

    usuario557219

    7 de septiembre de 2011 a las 7:55


  • k – intentaré mejorar la relación señal/ruido después de haber dormido un poco =)

    – Justin

    7 de septiembre de 2011 a las 7:58

  • @bcattle generalmente recomiendo que una biblioteca defina su propia definición. es mejor evitar la introducción de bibliotecas dependientes para estas definiciones simples. Ver: stackoverflow.com/questions/17668018/…. y sí, he encontrado varios programas que asumieron incorrectamente que otra biblioteca (por ejemplo, Foundation, UIKit, AppKit, etc.) estaría visible/disponible. no es bueno para la portabilidad, la reutilización o los tiempos de construcción. también evita que las traducciones de c usen el encabezado (lo que puede ser razonable o no, dependiendo de lo que se declare en ese encabezado).

    – Justin

    14 de enero de 2015 a las 4:26

extern no significa “global”, significa “definido en otro lugar”. Se usa para decirle al compilador que existe una variable o función (en otro archivo de objeto o biblioteca), para que no se queje y que el enlazador reciba 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 también está disponible en Objective-C, con la misma sintaxis y semántica. No hay una construcción de C que se defina de otra manera en Objective-C.

  • Gracias. Entonces, ¿siempre necesito importar el encabezado que contiene la declaración externa, si quiero usar el método/variable externo?

    – aneurisma

    7 de septiembre de 2011 a las 8:18


  • 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?

    – aneurisma

    7 de septiembre de 2011 a las 8:20

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

    – Mouviciel

    7 de septiembre de 2011 a las 8:22

  • Veo bien. Entonces, última pregunta. ¿Es externo más conveniente que declarar métodos estáticos o variables? Necesito importar el archivo de encabezado de todos modos, ¿correcto?

    – aneurisma

    7 de septiembre de 2011 a las 8:28


  • El archivo de encabezado debe contener variables que se declaran extern. escribir un extern declaración en su archivo .m o importarlo desde un archivo .h depende de cómo esté organizado su código.

    – Mouviciel

    7 de septiembre de 2011 a las 8:46

avatar de usuario
Vlad

Punto 3: Sí, puede usar FOUNDATION_EXPORT en el objetivo C, que es una macro que se resuelve con una palabra clave diferente dependiendo de si compila C o C ++

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad