2008-10-31 5 views
30

Me he enseñado a mí mismo Objective-C durante el último mes (soy un jefe de Java) y tengo mi cerebro envuelto en la mayor parte de ahora. Una cosa que me está confundiendo en este momento: ¿Cuál es la diferencia entre importar una clase a través de @class y hacer un #import?¿Cuál es la diferencia entre # import y @class, y cuándo debo usar uno sobre el otro?

¿Es uno mejor que otro, o necesito usar uno en lugar del otro en ciertos casos? Hasta ahora he estado usando solo #import.

Respuesta

66

#import trae todo el archivo de encabezado en cuestión en el archivo actual; cualquier archivo que ESO archivo #import s también se incluyen. @class, por otro lado (cuando se usa solo en una línea con algunos nombres de clase), simplemente le dice al compilador "Oye, vas a ver un nuevo token pronto; es una clase, así que trátalo de esa manera).

Esto es muy útil cuando tiene la posibilidad de 'circular incluye'; es decir, Object1.h hace referencia a Object2, y Object2.h hace referencia a Object1. Si #import ambos archivos en el otro, el compilador puede confundirse ya que trata de #import Object1.h, se ve en ella y ve Object2.h, sino que intenta #import Object2.h, y ve Object1.h, etc.

Si, por el contrario, cada uno de esos archivos tiene @class Object1; o @class Object2;, entonces no hay referencia circular. t asegúrese de realmente #import los encabezados necesarios en sus archivos de implementación (.m).

+2

Ben, Ben, que no tiene que responder a la pregunta CADA cacao desbordamiento de pila. ¡Te quemarás! – schwa

+2

debe ... parar ... responder ... –

5

La otra cosa que debes tener en cuenta es que #imports reduce la velocidad de tus tiempos de compilación, ya que significa que el compilador necesita extraer y trabajar con muchos más archivos de encabezado. Esto está principalmente enmascarado por el uso de encabezados precompilados, pero ocasionalmente he recibido proyectos que corss importó cada encabezado en lugar de utilizar @class cuando corresponda, y corregirlos puede mejorar el tiempo de compilación. Es sutil que el sistema refuerce el hecho de que si solo usas lo que realmente necesitas las cosas van más rápido.

Como regla general, siempre uso declaraciones de clase en mis archivos de encabezado y solo importo la superclase. Eso coincide con las sugerencias de Ben, pero pensé que valía la pena señalar que incluso si no está preocupado por las referencias circulares, es buena idea limitar #imports en los archivos de encabezado si puede.

27

@class se llama forward declaration. Básicamente le estás diciendo al compilador que la clase existe, pero no nada sobre la clase. Por lo tanto, no sabe cosas como su superclase y qué métodos declara.

Como regla general, use @class en .h y #import en el .m, si es posible. Como dijo Louis, esto ayudará a acelerar los tiempos de compilación. Sin embargo, hay momentos en los que necesita #import una clase en el encabezado. Los casos que se me ocurre en este momento son:

  • Usted está subclassing otra clase
  • Está implementando un protocolo

En estos casos, debe #import el archivo de cabecera donde la clase o protocolo es declarado porque el compilador necesita conocer la jerarquía de clase completa de sus clases principales y los protocolos de implementación.

Fwiw, puede reenviar declarar protocolos, también, siempre y cuando su no implementarlas:

@protocol SomeProtocol; 

@interface ... 

- (id<SomeProtocol>)someMethod; 

@end 
Cuestiones relacionadas