para musculares estiramientos estiramiento espalda cruzadas cadenas objective-c cocoa cocoa-touch xcode

objective c - musculares - Cuándo usar una cadena estática vs.#define



estiramiento global de cadenas musculares cruzadas para la espalda (6)

Consulte "static const" vs "#define" versus "enum" . La principal ventaja de la static es la seguridad del tipo.

Aparte de eso, el enfoque #define introduce una flexibilidad de concatenación de cadenas en línea que no se puede hacer con variables estáticas, por ejemplo

#define ROOT_PATH @"/System/Library/Frameworks" [[NSBundle bundleWithPath:ROOT_PATH@"/UIKit.framework"] load];

pero este probablemente no es un buen estilo :).

Estoy un poco confundido sobre cuándo es mejor usar:

static NSString *AppQuitGracefullyKey = @"AppQuitGracefully";

en lugar de

#define AppQuitGracefullyKey @"AppQuitGracefully"

He visto preguntas como esta para C o C ++, y creo que lo que es diferente aquí es que esto es específicamente para Objective C, utilizando un objeto, y en un dispositivo como el iPhone, puede haber problemas de pila, espacio de código o memoria que Todavía no entiendo.

Un uso sería:

appQuitGracefully = [[NSUserDefaults standardUserDefaults] integerForKey: AppQuitGracefullyKey];

¿O es solo una cuestión de estilo?

Gracias.


Después de hacer una búsqueda ( this pregunta / respuesta, entre otras cosas), creo que es importante decir que en cualquier momento cuando está utilizando una cadena literal @"AppQuitGracefully" se crea la cadena constante, y no importa cuántas veces la use, apuntará a el mismo objeto

Así que creo (y me disculpo si me equivoco) que esta oración en la respuesta anterior es incorrecta: If you use a #define, there will be a separate copy of the string stored in the source on each use.


En realidad, yo no recomendaría ninguno, debería usar extern lugar. Objective-c ya define FOUNDATION_EXPORT que es más portable que extern , por lo que una instancia global de NSString se vería así:

.h

FOUNDATION_EXPORT NSString * const AppQuitGracefullyKey;

.metro

NSString * const AppQuitGracefullyKey = @"AppQuitGracefully";

Normalmente los pongo en archivos de declaración (como MyProjectDecl.h ) e importo cuando lo necesito.

Hay algunas diferencias con estos enfoques:

  • #define tiene varias desventajas, como no ser seguro. Es cierto que hay soluciones para eso (como #define ((int)1) ), pero ¿cuál es el punto? Y, además, hay desventajas de depuración para ese enfoque. Los compiladores prefieren constantes. Vea this discusión.
  • los globales estáticos son visibles en el archivo que se declaran.
  • extern hace que la variable sea visible para todos los archivos. Eso contrasta con la estática.

Estático y externo difieren en visibilidad. También es notable que ninguno de estos enfoques duplica la cadena (ni siquiera #define ) ya que el compilador utiliza el Interlocutor de cadenas para evitarlo. En here , muestran pruebas:

NSString *a = @"Hello"; NSString *b = @"Hello"; BOOL wtf = (a == b); // YES

El operador == devuelve YES solo si las dos variables apuntan a la misma instancia. Y como pueden ver, lo hace.

La conclusión es: use FOUNDATION_EXPORT para constantes globales. Es fácil de depurar y será visible independientemente de su proyecto.


Si usa una estática, el compilador insertará exactamente una copia de la cadena en su binario y simplemente pasará los punteros a esa cadena, lo que resultará en binarios más compactos. Si usa #define, habrá una copia separada de la cadena almacenada en la fuente en cada uso. La combinación constante de cadenas manejará muchos de los dups pero hará que el enlazador trabaje más sin ninguna razón.


Utilizo static cuando necesito exportar símbolos NSString desde una biblioteca o un marco. Uso #define cuando necesito una cadena en muchos lugares que puedo cambiar fácilmente. De todos modos, el compilador y el enlazador se encargarán de las optimizaciones.


USANDO #define:

no puedes depurar el valor del identificador

trabajar con #define y otras macros es un trabajo de Pre-Procesador, cuando aciertes primero Build / Run preprocesará el código fuente, funcionará con todas las macros (comenzando con el símbolo #),

Supongamos que ha creado

#define LanguageTypeEnglish @"en"

y lo usé en 2 lugares en tu código.

NSString *language = LanguageTypeEnglish; NSString *languageCode = LanguageTypeEnglish;

Reemplazará "LanguageTypeEnglish" con @"en" , en todos los lugares. Entonces se generarán 2 copias de @"en" . es decir

NSString *language = @"en"; NSString *languageCode = @"en";

Recuerde, hasta este proceso, el compilador no está en la imagen.

Después de preprocesar todas las macros, el compilador aparece en la imagen, y obtendrá un código de entrada como este,

NSString *language = @"en"; NSString *languageCode = @"en";

y compilarlo.

UTILIZANDO estático:

respeta el alcance y es seguro para el tipo. puedes depurar el valor del identificador

Durante el proceso de compilación, si se encuentra el compilador,

static NSString *LanguageTypeRussian = @"ru";

entonces se verificará si la variable con el mismo nombre se guardó previamente, si es así, solo pasará el puntero de esa variable, si no, creará esa variable y pasará su puntero, la próxima vez solo pasará el puntero de lo mismo.

Entonces, usando estático, solo se genera una copia de la variable dentro del alcance.