@import vs#import-iOS 7
objective-c ios7 (5)
Estoy jugando con algunas de las nuevas características de iOS 7 y trabajando con algunos de los efectos de imagen como se explica en el video de la WWDC "Implementing Engaging UI en iOS". Para producir un efecto de desenfoque dentro del código fuente de la sesión, UIImage
se extendió a través de una categoría que importa UIKit así:
@import UIKit;
Creo que vi algo sobre esto en otro video de sesión, pero tengo problemas para encontrarlo. Estoy buscando cualquier información de fondo sobre cuándo usar esto. ¿Se puede usar solo con marcos de Apple? ¿Los beneficios de usar esta directiva de compilación son suficientes para volver atrás y actualizar el código antiguo?
Actualmente solo funciona para los marcos de sistema integrados. Si usa #import
como Apple, todavía importa el marco UIKit
en el delegado de la aplicación al que se reemplaza (si los módulos están UIKit
y se reconoce como marco del sistema) y el compilador lo reasignará como una importación de módulos y no una importación de archivos de cabecera de todos modos. Por lo tanto, dejar el #import
será el mismo que su conversión a un módulo de importación cuando sea posible de todos modos
Buena respuesta que puedes encontrar en el libro Learning Cocoa with Objective-C (ISBN: 978-1-491-90139-7)
Los módulos son un nuevo medio de incluir y vincular archivos y bibliotecas en sus proyectos. Para entender cómo funcionan los módulos y qué beneficios tienen, es importante mirar hacia atrás en el historial de Objective-C y la declaración de #import. Cuando quiera incluir un archivo para su uso, generalmente tendrá un código similar al siguiente:
#import "someFile.h"
O en el caso de los marcos:
#import <SomeLibrary/SomeFile.h>
Debido a que Objective-C es un superconjunto del lenguaje de programación C, el estado #import es un refinamiento menor en la declaración #include
de C. La declaración #include es muy simple; copia todo lo que encuentra en el archivo incluido en su código durante la compilación. Esto a veces puede causar problemas significativos. Por ejemplo, imagine que tiene dos archivos de encabezado: SomeFileA.h
SomeFileB.h
; SomeFileA.h
incluye SomeFileB.h
, y SomeFileB.h
incluye SomeFileA.h
. Esto crea un bucle, y puede confundir al coimpilador. Para lidiar con esto, los programadores de C tienen que escribir guardas contra este tipo de evento para que no ocurra.
Cuando use #import
, no necesita preocuparse por este problema o escribir protectores de encabezado para evitarlo. Sin embargo, #import
sigue siendo solo una acción glorificada de copiar y pegar, lo que provoca un tiempo de compilación lento entre una serie de otros problemas más pequeños pero aún muy peligrosos (como un archivo incluido que invalida algo que ha declarado en otro lugar en su propio código).
Los módulos son un intento de evitar esto. Ya no son una copia y pegado en el código fuente, sino una representación serializada de los archivos incluidos que se pueden importar a su código fuente solo cuando y donde se necesitan. Al usar módulos, el código generalmente se compilará más rápido y será más seguro que usar #include o #import
.
Volviendo al ejemplo anterior de importar un framework:
#import <SomeLibrary/SomeFile.h>
Para importar esta biblioteca como un módulo, el código se cambiaría a:
@import SomeLibrary;
Esto tiene la ventaja adicional de que Xcode vincula automáticamente el marco de SomeLibrary con el proyecto. Los módulos también le permiten incluir solo los componentes que realmente necesita en su proyecto. Por ejemplo, si desea usar el componente AwesomeObject en el marco de AwesomeLibrary, normalmente tendría que importar todo solo para usar la pieza. Sin embargo, al usar módulos, solo puede importar el objeto específico que desea usar:
@import AwesomeLibrary.AwesomeObject;
Para todos los nuevos proyectos realizados en Xcode 5, los módulos están habilitados de forma predeterminada. Si desea utilizar módulos en proyectos anteriores (y debería hacerlo), deberán habilitarse en la configuración de compilación del proyecto. Una vez que lo haga, puede usar las declaraciones #import
y @import
en su código juntas sin ninguna preocupación.
Es una nueva característica llamada Módulos o "importación semántica". Hay más información en los videos de la WWDC 2013 para las sesiones 205 y 404 . Es una especie de mejor implementación de los encabezados precompilados. Puede usar módulos con cualquiera de los marcos del sistema en iOS 7 y Mavericks. Los módulos son un paquete de la estructura ejecutable y sus encabezados, y se consideran más seguros y eficientes que #import
.
Una de las grandes ventajas de usar @import
es que no necesita agregar el marco en la configuración del proyecto, se realiza de forma automática . Eso significa que puede omitir el paso donde hace clic en el botón más y buscar el marco (caja de herramientas dorada), y luego lo mueve al grupo "Marcos". Salvará a muchos desarrolladores de los mensajes crípticos de "error de vinculador".
En realidad no es necesario utilizar la palabra clave @import
. Si opta por usar módulos, todas las directivas #import
y #include
se asignan para usar @import
automáticamente. Eso significa que no tiene que cambiar su código fuente (o el código fuente de las bibliotecas que descarga desde otro lugar). Supuestamente, el uso de módulos también mejora el rendimiento de la compilación, especialmente si no ha estado usando bien los PCH o si su proyecto tiene muchos archivos de origen pequeños.
Los módulos están preconstruidos para la mayoría de los marcos de Apple (UIKit, MapKit, GameKit, etc.). Puede usarlos con los marcos que cree usted mismo: se crean automáticamente si crea un marco Swift en Xcode, y puede crear manualmente un archivo ".modulemap" para cualquier biblioteca de Apple o de terceros .
Puede usar el código completado para ver la lista de marcos disponibles:
Los módulos están habilitados de forma predeterminada en nuevos proyectos en Xcode 5 . Para habilitarlos en un proyecto anterior, vaya a la configuración de compilación de su proyecto, busque "Módulos" y configure "Habilitar módulos" en "SÍ". Los "Marcos de Enlace" también deben ser "SÍ":
Debe utilizar Xcode 5 y el iOS 7 o el SDK de Mavericks, pero aún puede lanzar para sistemas operativos más antiguos (por ejemplo, iOS 4.3 o lo que sea). Los módulos no cambian la forma en que se construye su código o cualquiera de los códigos fuente.
De las diapositivas de la WWDC:
- Importa la descripción semántica completa de un framework.
- No es necesario analizar los encabezados.
- Mejor manera de importar la interfaz de un framework
- Cargas de representación binaria.
- Más flexible que los encabezados precompilados
- Inmune a los efectos de las definiciones de macros locales (p. Ej.,
#define readonly 0x01
)- Habilitado para nuevos proyectos por defecto
Para utilizar explícitamente los módulos:
Reemplace #import <Cocoa/Cocoa.h>
con @import Cocoa;
También puede importar un solo encabezado con esta notación:
@import iAd.ADBannerView;
Los submódulos se completan automáticamente en Xcode.
Hay algunos beneficios de usar módulos. Puede usarlo solo con el marco de Apple a menos que se cree un mapa de módulo. @import
es un poco similar a la .pch
archivos de encabezados cuando se agrega a .pch
archivo .pch
, que es una forma de ajustar la aplicación del proceso de compilación. Además, no tiene que agregar bibliotecas de la forma anterior, de hecho, usar @import
es mucho más rápido y eficiente. Si aún busca una buena referencia, le recomiendo que lea este artículo .
Parece que desde XCode 7.x se emiten muchas advertencias al habilitar el módulo de CLANG_ENABLE_MODULES
con CLANG_ENABLE_MODULES
Echa un vistazo a Muchas advertencias cuando construyas con Xcode 7 con bibliotecas de terceros