Desde que comencé a trabajar en aplicaciones iOS y el objetivo C, me han desconcertado mucho las diferentes ubicaciones donde se podrían declarar y definir variables. Por un lado tenemos el enfoque tradicional de C, por el otro tenemos las nuevas directivas ObjectiveC que agregan OO encima de eso. ¿Podrían ayudarme a comprender las mejores prácticas y las situaciones en las que me gustaría usar estas ubicaciones para mis variables y quizás corregir mi comprensión actual?
Aquí hay una clase de muestra (.h y .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
@interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
@end
y
#import "SampleClass.h"
// 4) what goes here?
@interface SampleClass()
// 5) private interface, can define private methods and properties here
@end
@implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
@end
- Mi comprensión de 1 y 4 es que esas son declaraciones y definiciones basadas en archivos de estilo C que no comprenden en absoluto el concepto de clase y, por lo tanto, deben usarse exactamente como se usarían en C.Las he visto utilizado para implementar singletons basados en variables estáticas antes. ¿Hay otros usos convenientes que me falta?
- Mi opinión al trabajar con iOS es que los ivars se han eliminado casi por completo fuera de la directiva @synthesize y, por lo tanto, se pueden ignorar en su mayoría. ¿Es ese el caso?
- Con respecto a 5: ¿por qué querría declarar métodos en interfaces privadas? Mis métodos de clase privada parecen compilarse bien sin una declaración en la interfaz. ¿Es principalmente por legibilidad?
¡Muchas gracias, amigos!
fuente
Primero, lea la respuesta de @ DrummerB. Es una buena descripción de los porqués y lo que debe hacer en general. Con eso en mente, a sus preguntas específicas:
No hay definiciones de variables reales aquí (es técnicamente legal hacerlo si sabe exactamente lo que está haciendo, pero nunca lo haga). Puede definir varios otros tipos de cosas:
Los externos parecen declaraciones de variables, pero son solo una promesa de declararlos en otro lugar. En ObjC, solo deben usarse para declarar constantes y, en general, solo constantes de cadena. Por ejemplo:
Luego, en su
.m
archivo declararía la constante real:Como señaló DrummerB, esto es un legado. No pongas nada aquí.
Sí.
Constantes externas, como se describe arriba. También las variables estáticas de archivos pueden ir aquí. Son el equivalente a las variables de clase en otros lenguajes.
Sí
Pero muy raramente. Casi siempre debes permitir que clang (Xcode) cree las variables por ti. Las excepciones generalmente son alrededor de ivars que no son de ObjC (como objetos Core Foundation, y especialmente objetos C ++ si se trata de una clase ObjC ++), o ivars que tienen una semántica de almacenamiento extraña (como ivars que no coinciden con una propiedad por alguna razón).
En general, ya no deberías @synthesize. Clang (Xcode) lo hará por ti, y deberías dejarlo.
En los últimos años, las cosas se han vuelto dramáticamente más simples. El efecto secundario es que ahora hay tres eras diferentes (ABI frágil, ABI no frágil, ABI no frágil + auto-síntesis). Entonces, cuando vea el código anterior, puede resultar un poco confuso. Así, la confusión que surge de la simplicidad: D
fuente
También soy bastante nuevo, así que espero no estropear nada.
1 y 4: Variables globales de estilo C: tienen un alcance de archivo amplio. La diferencia entre los dos es que, dado que tienen todo el archivo, el primero estará disponible para cualquiera que importe el encabezado, mientras que el segundo no.
2: variables de instancia. La mayoría de las variables de instancia se sintetizan y recuperan / configuran a través de accesos usando propiedades porque hace que la administración de la memoria sea agradable y simple, así como también le brinda una notación de puntos fácil de entender.
6: Los ivars de implementación son algo nuevos. Es un buen lugar para colocar ivars privados, ya que solo desea exponer lo que se necesita en el encabezado público, pero las subclases no los heredan AFAIK.
3 y 7: Declaraciones públicas de métodos y propiedades, luego implementaciones.
5: Interfaz privada. Siempre uso interfaces privadas siempre que puedo para mantener las cosas limpias y crear una especie de efecto de caja negra. Si no necesitan saberlo, póngalo allí. También lo hago por legibilidad, no sé si hay otras razones.
fuente
Este es un ejemplo de todo tipo de variables declaradas en Objective-C. El nombre de la variable indica su acceso.
Archivo: Animal.h
Archivo: Animal.m
Tenga en cuenta que las variables iNotVisible no son visibles desde ninguna otra clase. Este es un problema de visibilidad, por lo que declararlos con
@property
o@public
no lo cambia.Dentro de un constructor, es una buena práctica acceder a las variables declaradas con
@property
subrayado en su lugarself
para evitar efectos secundarios.Intentemos acceder a las variables.
Archivo: Cow.h
Archivo: Cow.m
Todavía podemos acceder a las variables no visibles usando el tiempo de ejecución.
Archivo: Cow.m (parte 2)
Intentemos acceder a las variables no visibles.
Archivo: main.m
Esto imprime
Tenga en cuenta que pude acceder al ivar de respaldo
_iNotVisible2
que es privado para la subclase. En Objective-C se pueden leer o configurar todas las variables, incluso aquellas que están marcadas@private
, sin excepciones.No incluí objetos asociados o variables C ya que son aves diferentes. En cuanto a las variables C, cualquier variable definida fuera de
@interface X{}
o@implementation X{}
es una variable C con alcance de archivo y almacenamiento estático.No hablé de los atributos de administración de memoria, ni de los atributos de solo lectura / lectura y escritura, captador / configurador.
fuente