2011-04-06 16 views
7

¿Cuál es la diferencia entre declarar un ivar dentro de un @interface versus poner una variable dentro de un @implementation en un archivo .m?Diferencia entre declarar un ivar en @interface y poner variable en @implementation

@interface MyClass : NSObject { 
    int num; 
} 
- (void)doSomething; 
@end 

vs

@implementation MyClass 
int num2; 

- (void)doSomething { 
    num = 137; 
    num2 = 138; 
} 
@end 

¿Hay siempre un momento en que usted quiere poner una variable dentro del @implementation?

Respuesta

8

La diferencia entre usar un ivar y declarar una variable dentro de la implementación es que la variable dentro de la implementación se encuentra en el alcance del archivo y es global. Eso significa que todas las instancias (y cualquier método estático) compartirán la misma variable; es decir, si una instancia de su objeto cambia la variable, la cambiará para todas las instancias.

El caso de uso para definirlo en el alcance del archivo es almacenar cosas para métodos estáticos (métodos que actúan directamente sobre la clase en lugar de una instancia de la clase). Un caso de uso muy común para esto es el patrón de diseño de Singleton. Puede definir una instancia estática de su clase dentro de este archivo para que, en cualquier momento, pueda asegurarse de que está accediendo a la misma instancia. Puede proporcionar un método estático que devuelva esta instancia para que cualquier objeto en su código pueda acceder a ese mismo objeto llamando al método directamente en su clase.

actualización 4/17/14

La práctica común es utilizar ahora Properties. Esto crea getters y setters para que automáticamente la clase sea más extensible (si decides cambiar la forma en que funciona una propiedad, quizás quieras cambiarla para que siempre se calcule sobre la marcha, la interfaz pública de la clase no necesita cambiarse).)

Puede usar private class extensions to declare "private" properties and methods. Esto tiene el efecto de proteger determinadas propiedades y métodos de acceder a clases externas.

+0

Una muy buena explicación podría ser esta: [Variable de clase definida en @implementation en vez de @interface?] (Http://stackoverflow.com/a/2571565/818506) –

+0

Esta respuesta es un poco anticuada. Ahora es mucho mejor poner los ivars en la 'implementación @' pero asegúrese de usar llaves. Si está entre llaves, las variables serán variables de instancia. Sin las llaves, las variables serán variables globales. – rmaddy

+0

"mucho mejor" es una exageración. Diría que quieres ponerlo en el archivo de implementación siempre que sea una variable con la que otras clases no deberían estar jugando. Sin embargo, generalmente es preferible usar propiedades ahora. Puede usar [extensiones de clase privadas para declarar propiedades y métodos "privados"] (https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW6). – drewag

5

Por lo que sé, poner una declaración de variable dentro de @implementation no es diferente de ponerlo fuera de la implementación: no es un ivar, es solo una variable declarada en el alcance del archivo.

Un uso es para declarar el equivalente de miembros estáticos de C++. Por ejemplo:

@implementation MyClass 

static int s_count = 0; 

- (id)init { 
    if ((self = [super init])) 
    ++s_count; 
    return self; 
} 

- (void)dealloc { 
    --s_count; 
    [super dealloc]; 
} 

Suponiendo init es su única inicializador, entonces s_count contendrá el número total de casos de MyClass que están activos.

+2

es decir, las variables globales estáticas se pueden utilizar como variables de clase. –

+2

Estaba hablando con algunas personas al respecto y dijeron que el ivar es una variable de instancia, mientras que la variable declarada dentro de @implementation es "global, como en no por instancia". Para mí eso suena como estático. Obtengo lo que es el ivar, pero todavía no está claro acerca de la variable dentro de una implementación y cuándo debería usarse. – nickfox

+5

@nickfox _Variables globales_, estáticas o no, tienen la misma duración que el programa y pueden ser utilizadas por cualquier método o función en el archivo de implementación, por lo que se pueden usar como variables de clase. Una variable global no estática también puede ser utilizada por otros archivos de implementación, similar a una variable de clase pública. Una variable global estática_ solo puede ser utilizada por el archivo de implementación que la declara, por lo tanto, actúa como una variable de clase privada. –

1

Nota: Históricamente, la interfaz requería declaraciones de las variables de instancia de una clase, las estructuras de datos que forman parte de cada instancia de la clase. Estos se declararon entre llaves después de la declaración @interface y antes de las declaraciones de métodos:

Las variables de instancia representan un detalle de implementación y, por lo general, no se debe acceder fuera de la clase. Además, puede declararlos en el bloque de implementación o sintetizarlos usando propiedades declaradas. Por lo general, no debe declarar variables de instancia en la interfaz pública, por lo que debe omitir las llaves.

(source)

Cuestiones relacionadas