2010-02-26 11 views
10

Veo una gran cantidad de código objetivo-c que simplemente # define las constantes locales que necesita, y luego continúa de manera feliz. El problema es que, hasta donde yo sé, #defines no tienen alcance. Muchos de ellos están en el código de ejemplo de Apple. Por ejemplo, en el TableViewSuite ejemplo 5, la función drawRect en TimeZoneView.m contiene el bloque siguiente:Mejores prácticas para las constantes locales en el objetivo-c

#define LEFT_COLUMN_OFFSET 10 
#define LEFT_COLUMN_WIDTH 130 

#define MIDDLE_COLUMN_OFFSET 140 
#define MIDDLE_COLUMN_WIDTH 110 

#define RIGHT_COLUMN_OFFSET 270 

#define UPPER_ROW_TOP 8 
#define LOWER_ROW_TOP 34 

#define MAIN_FONT_SIZE 18 
#define MIN_MAIN_FONT_SIZE 16 
#define SECONDARY_FONT_SIZE 12 
#define MIN_SECONDARY_FONT_SIZE 10 

¿Hay alguna razón que no entiendo que esto no es absurdamente peligroso? Como mínimo, ¿no deberíamos #undef estas constantes al final de la función?

Esa es mi pregunta supongo:

¿Es una mejor práctica para definir lo que necesita en el archivo que lo necesite, y poco lo definen al final? ¿O crees que es mejor usar consts estáticos para este tipo de cosas? ¿Hay alguna penalización de rendimiento al usar consts estáticos, o el compilador puede manejarlos tan eficientemente como #define?

Respuesta

13

#defines en archivos de implementación (.m) por definición se limitan al archivo en el que se encuentran, ya que nadie más #include es un archivo .m. (Usted hace quieren pensar cuidadosamente acerca de esto en los archivos de cabecera común, donde el tema de alcance que mencionas es real, y SO_QUESTION_2345197_NAMESPACE_YOUR_CONSTANTS_APPROPRIATELY.)

Para constantes locales en los archivos de implementación que es lo que parece estar preguntando, #define es más eficiente de compilar, pero no obtiene los símbolos cuando depura. Las ventajas locales tienen ese beneficio, y en algunos casos (¿constantes de cadena? ¿De acuerdo?) Impiden la duplicación de datos constantes en el binario, aunque en este punto del mundo, el tamaño y la eficiencia de compilación (y la eficacia del tiempo de ejecución para buscarlos) es básicamente ruido a menos que perfile un circuito cerrado y encuentre un problema con él.

+1

Genial, gracias Ben, creo que eso responde. Estoy de acuerdo en que es probablemente trivial, pero las cosas triviales pueden sumarse y, en igualdad de condiciones, prefiero tener el hábito de usar las convenciones de rendimiento por defecto. De esa manera, cuando encuentres un caso donde importa, ya tienes el hábito de hacerlo. – DougW

+1

Constantes de cadena, es decir, las definidas con @ "" son singleton/atoms y dicen un poco de memoria y tiempo. NSNumbers son de la misma manera. En cualquier proceso dado, solo hay una instancia generada por [NSNumber numberWithInt: 1]. – TechZen

+0

NSNumber pone en práctica un subconjunto pequeño, no el rango completo de enteros, mientras que las NSStrings constantes siempre se intercalarán – rpetrich

8

Últimamente, comencé a usar métodos de clase para almacenar constantes. Lo comencé como un truco para almacenar los nombres de las claves en un modelo de Data Core impío y enorme. Sin embargo, se ha demostrado que es bastante eficiente tanto en el código como en la perspectiva de creación y mantenimiento de la base de código. Genero una categoría así:

@interface MyClass (KeyNames) 
+ (NSString *) creationDate_Key; 
@end 

@implementation MyClass (KeyNames) 

+ (NSString *) creationDate_Key{ 
    return @"creationDate"; 
} 
@end 

Entonces usarlo como:

NSString *key=[MyClass creationDate_Key]; 

Tengo un script que genera los métodos para mí. Lo bueno es que tienen un alcance, heredado y más compacto de lo que define el tiempo. Si necesito usar la clave mucho, como en un bucle, simplemente la estaciono en una variable local si la eficiencia se convierte en un problema.

+2

Simplemente curioso, cuando haces esto, ¿crea un nuevo objeto 'NSString' (' @ "creationDate" ') en la memoria cada vez que haces referencia' creationDate_Key'? –

+0

No, no es así. Las cadenas creadas con @ son especiales. –

Cuestiones relacionadas