objective-c import include

objective c - ¿Cuál es la diferencia entre#import y#include en Objective-C?



(9)

En caso de que tuviera una variable global en uno de mis archivos .h que estaba causando el problema, y ​​lo resolví agregando extern delante de él.

¿Cuáles son las diferencias entre #import y #include en Objective-C y hay ocasiones en las que debería usar una sobre la otra? ¿Está uno en desuso?

Estaba leyendo el siguiente tutorial: http://www.otierney.net/objective-c.html#preamble y su párrafo sobre #import y #include parece contradecirse o, al menos, no está claro.


Estoy de acuerdo con Jason.

Me sorprendió haciendo esto:

#import <sys/time.h> // to use gettimeofday() function #import <time.h> // to use time() function

Para GNU gcc, seguía quejándose de que la función time () no estaba definida.

Entonces cambié #import a #include y todo salió bien.

Razón:

Usted #import <sys / time.h>:
<sys / time.h> incluye solo una parte de <time.h> usando #defines

Usted #importar <time.h>:
No vayas. Aunque solo una parte de <time.h> ya estaba incluida, como
En lo que respecta a #import, ese archivo ya está completamente incluido.

Línea de fondo:

Los encabezados C / C ++ tradicionalmente incluyen partes de otros archivos de inclusión.
Así que para los encabezados C / C ++, use #include.
Para los encabezados objc / objc ++, use #import.


Parece que hay mucha confusión con respecto al preprocesador.

Lo que el compilador hace cuando ve un #include que reemplaza esa línea con el contenido de los archivos incluidos, sin preguntas.

Así que si tienes un archivo ah con este contenido:

typedef int my_number;

y un archivo bc con este contenido:

#include "a.h" #include "a.h"

El preprocesador traducirá el archivo bc antes de compilarlo.

typedef int my_number; typedef int my_number;

lo que dará como resultado un error de compilación, ya que el tipo my_number se define dos veces. Aunque la definición es la misma, el lenguaje C no lo permite.

Dado que un encabezado a menudo se usa en más de un lugar, las guardas de inclusión generalmente se usan en C. Esto se ve así:

#ifndef _a_h_included_ #define _a_h_included_ typedef int my_number; #endif

El archivo bc todavía tendría todo el contenido del encabezado dos veces después de ser preprocesado. Pero la segunda instancia se _a_h_included_ ya que la macro _a_h_included_ ya se habría definido.

Esto funciona realmente bien, pero tiene dos inconvenientes. Primero que todo, los guardias de inclusión deben escribirse, y el nombre de la macro debe ser diferente en cada encabezado. Y en segundo lugar, el compilador todavía tiene que buscar el archivo de encabezado y leerlo con la frecuencia que se incluye.

Objective-C tiene la instrucción de preprocesador #import (también se puede usar para código C y C ++ con algunos compiladores y opciones). Esto hace casi lo mismo que #include , pero también señala internamente qué archivo ya se ha incluido. La línea #import solo se reemplaza por el contenido del archivo nombrado por primera vez que se encuentra. Cada vez después de eso se ignora.


Sé que este hilo es antiguo ... pero en los "tiempos modernos" ... hay una estrategia de "inclusión" muy superior a través de los módulos @import de @import , que a menudo se pasa por alto.

Los módulos mejoran el acceso a la API de las bibliotecas de software al reemplazar el modelo de inclusión de preprocesador textual con un modelo semántico más robusto y más eficiente. Desde la perspectiva del usuario, el código se ve ligeramente diferente, porque uno usa una declaración de importación en lugar de una directiva de preprocesador #include:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

o

@import Foundation; // Like #import <Foundation/Foundation.h> @import ObjectiveC; // Like #import <objc/runtime.h>

Sin embargo, esta importación de módulos se comporta de manera muy diferente a la correspondiente #include: cuando el compilador ve la importación de módulos anterior, carga una representación binaria del módulo y pone su API a disposición de la aplicación directamente. Las definiciones de preprocesador que preceden a la declaración de importación no tienen ningún impacto en la API proporcionada ... porque el módulo mismo se compiló como un módulo independiente, independiente. Además, todos los indicadores de vinculador necesarios para utilizar el módulo se proporcionarán automáticamente cuando se importe el módulo. Este modelo de importación semántica aborda muchos de los problemas del modelo de inclusión del preprocesador.

Para habilitar los módulos, pase el indicador de la línea de comando -fmodules aka CLANG_ENABLE_MODULES en Xcode - en el momento de la compilación. Como se mencionó anteriormente, esta estrategia obvia CUALQUIERA y TODAS LAS LDFLAGS . Al igual que en, puede QUITAR cualquier configuración de "OTHER_LDFLAGS", así como cualquier fase de "Enlace".

Encuentro los tiempos de compilación / lanzamiento para "sentirse" más ágil (o posiblemente, ¿hay un retraso menor al "enlazar"?) ... y también, ofrece una gran oportunidad para purgar el ahora extraño Proyecto-Prefijo.pch archivo, y configuración de compilación correspondiente, GCC_INCREASE_PRECOMPILED_HEADER_SHARING , GCC_PRECOMPILE_PREFIX_HEADER , y GCC_PREFIX_HEADER , etc.

Además, aunque no está bien documentado ... Puede crear module.map s para sus propios marcos e incluirlos de la misma manera conveniente. Puedes echar un vistazo a mi repositorio de github ObjC-Clang-Modules para ver algunos ejemplos de cómo implementar tales milagros.


SI #incluye un archivo dos veces en archivos .h, el compilador dará error. Pero si importas un archivo más de una vez, el compilador lo ignorará.


Si está familiarizado con C ++ y macros, entonces

#import "Class.h"

es parecido a

{ #pragma once #include "class.h" }

lo que significa que su clase se cargará solo una vez cuando se ejecute su aplicación.


#include funciona igual que C #include .

#import realiza un seguimiento de los encabezados que ya se han incluido y se ignora si un encabezado se importa más de una vez en una unidad de compilación. Esto hace que sea innecesario usar protectores de encabezado.

La conclusión es simplemente usar #import en Objective-C y no te preocupes si tus encabezados terminan importando algo más de una vez.


#include se usó para obtener "cosas" de otro archivo a la que se usa #include . Ej:

en el archivo: main.cpp

#include "otherfile.h" // some stuff here using otherfile.h objects, // functions or classes declared inside

La protección de encabezado se usa en la parte superior de cada archivo de encabezado (* .h) para evitar la inclusión del mismo archivo más de una vez (si sucede, obtendrá errores de compilación).

en el archivo: otherfile.h

#ifndef OTHERFILE #define OTHERFILE // declare functions, classes or objects here #endif

incluso si coloca #include "otherfile.h" n vez en su código, este no se volverá a declarar.


La directiva #import se agregó a Objective-C como una versión mejorada de #include. Si se ha mejorado o no, sin embargo, todavía es un tema de debate. #import garantiza que un archivo solo se incluya una vez para que nunca tenga un problema con los recursivos incluidos. Sin embargo, la mayoría de los archivos de encabezado decentes se protegen contra esto de todos modos, por lo que no es realmente un gran beneficio.

Básicamente, depende de ti decidir cuál quieres usar. Tiendo a #importar encabezados para cosas de Objective-C (como definiciones de clase y similares) y #incluir cosas de C estándar que necesito. Por ejemplo, uno de mis archivos de origen podría verse así:

#import <Foundation/Foundation.h> #include <asl.h> #include <mach/mach.h>