Jaka jest różnica między # import a # include w Objective-C?

Jakie są różnice między # import i #include w Objective-C i czy są czasy, w których powinieneś używać jednego nad drugim? Czy jeden jest przestarzały?

Czytałam poniższy tutorial: http://www.otierney.net/objective-c.html#preamble i jego akapit o # import i # include wydaje się przeczyć samemu sobie lub przynajmniej jest niejasny.

Author: Ryan Guill, 2009-01-13

9 answers

Dyrektywa #import została dodana do Objective-C jako ulepszona wersja # include. Jednak to, czy zostanie poprawiona, czy nie, jest nadal kwestią dyskusyjną. # import zapewnia, że plik jest dołączany tylko raz, więc nigdy nie masz problemu z rekurencyjnymi włącznikami. Jednak większość przyzwoitych plików nagłówkowych i tak chroni się przed tym, więc nie jest to tak naprawdę wielka korzyść.

Zasadniczo, to do ciebie należy decyzja, który chcesz użyć. Mam tendencję do # import nagłówków dla Objective - C rzeczy (takie jak definicje klas I takie) i #zawierają standardowe rzeczy C, których potrzebuję. Na przykład, jeden z moich plików źródłowych może wyglądać tak:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>
 328
Author: Jason Coco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-27 19:05:13

Wydaje się, że istnieje wiele nieporozumień dotyczących preprocesora.

Co robi kompilator, gdy widzi #include, że zastępuje tę linię zawartością dołączonych plików, bez zadawania pytań.

Więc jeśli Masz plik a.h z tą zawartością:

typedef int my_number;

Oraz Plik b.c o tej treści:

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

Plik b.c zostanie przetłumaczony przez preprocesor przed kompilacją do

typedef int my_number;
typedef int my_number;

Co spowoduje błąd kompilatora, ponieważ typ my_number jest zdefiniowany dwukrotnie. Mimo że definicja jest taka sama, nie jest to dozwolone przez język C.

Ponieważ nagłówek jest często używany w więcej niż jednym miejscu include guards zazwyczaj są używane w C. wygląda to tak:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

Plik b.c nadal będzie zawierał całą zawartość nagłówka dwa razy po uprzednim przetworzeniu. Ale druga instancja byłaby ignorowana, ponieważ makro _a_h_included_ byłoby już zdefiniowane.

To naprawdę działa ale ma dwie wady. Przede wszystkim należy zapisać strażników include, a nazwa makra musi być inna w każdym nagłówku. Po drugie kompilator musi nadal szukać pliku nagłówkowego i czytać go tak często, jak jest dołączony.

Objective-C posiada instrukcję preprocesora #import (może być również używana dla kodu C i c++ z niektórymi kompilatorami i opcjami). Robi to prawie tak samo jak #include, ale zauważa również wewnętrznie, który plik został już dołączony. Linia #import jest zastępowany przez zawartość nazwanego pliku tylko po raz pierwszy napotkany. Za każdym razem jest po prostu ignorowany.

 335
Author: Sven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-17 22:38:15

Zgadzam się z Jasonem.

Zostałem przyłapany na robieniu tego:

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

Dla GNU gcc narzekało, że funkcja time() była nie zdefiniowano.

Więc zmieniłem # import na #include i wszystko poszło ok.

Powód:

You # import :
     zawiera tylko część używając # definiuje

You # import :
    Nie ma mowy. Chociaż tylko część był już uwzględniony, jako
    far as # import dotyczy, że plik jest już całkowicie włączony.

Bottom line:

Nagłówki C / C++ tradycyjnie zawierają części innych plików nagłówkowych.
Tak więc dla nagłówków C / C++ użyj #include.
Dla nagłówków objc / objc++ użyj # import.

 61
Author: user512705,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-11 18:49:57

#include działa podobnie jak C #include.

#import śledzi, które nagłówki zostały już dołączone i jest ignorowane, jeśli nagłówek jest importowany więcej niż jeden raz w jednostce kompilacji. To sprawia, że nie ma potrzeby używania osłon nagłówkowych.

Najważniejsze jest użycie #import w Objective-C i nie martw się, jeśli Nagłówki będą importować coś więcej niż raz.

 22
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 16:28:39

Wiem, że ten wątek jest stary... ale w "współczesnych czasach".. istnieje znacznie lepsza "strategia dołączania" poprzez @import moduły - to jest często pomijane..

Moduły poprawiają dostęp do API bibliotek oprogramowania poprzez zastąpienie modelu włączenia preprocesora tekstowego bardziej solidnym i wydajniejszym modelem semantycznym. Z punktu widzenia użytkownika kod wygląda nieco inaczej, ponieważ używa się deklaracji importu zamiast preprocesora # include dyrektywa:

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

Lub

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

Jednakże import modułu zachowuje się zupełnie inaczej niż odpowiedni #include: gdy kompilator widzi import modułu powyżej, ładuje binarną reprezentację modułu i udostępnia jego API bezpośrednio aplikacji. Definicje preprocesora poprzedzające deklarację importową nie mają wpływu na udostępniony interfejs API... ponieważ sam moduł został skompilowany jako oddzielny, samodzielny moduł. Dodatkowo, wszelkie flagi linkera wymagane do użycia modułu zostaną automatycznie dostarczone podczas importowania modułu. Ten semantyczny model importu rozwiązuje wiele problemów związanych z modelem włączenia preprocesora.

Aby włączyć Moduły, podaj flagę linii poleceń -fmodules aka CLANG_ENABLE_MODULES w Xcode - podczas kompilacji. Jak wspomniano powyżej.. ta strategia eliminuje wszelkie LDFLAGS. Jak w, można usunąć wszelkie ustawienia "OTHER_LDFLAGS", a także wszelkie " linkowanie" fazy..

Tutaj wpisz opis obrazka

Uważam, że czasy kompilacji / uruchamiania "czują się" znacznie bardziej snappier (lub ewentualnie, jest po prostu mniej opóźnień podczas "linkowania"?).. a także, stanowi doskonałą okazję do oczyszczenia teraz obcy projekt-prefiks.plik pch i odpowiednie ustawienia budowania, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, i GCC_PREFIX_HEADER, itd.

Ponadto, choć nie jest to dobrze udokumentowane ... możesz tworzyć module.maps dla własnych frameworków i dołączać je w ten sam wygodny sposób. You can take a look at my ObjC-Clang-Modules github repo dla kilku przykładów jak zaimplementować takie cuda.

 11
Author: Alex Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-18 01:37:44

Jeśli znasz C++ i makra, to

#import "Class.h" 

Jest podobny do

{
#pragma once

#include "class.h"
}

Co oznacza, że Twoja klasa zostanie załadowana tylko raz, gdy Twoja aplikacja zostanie uruchomiona.

 3
Author: Evol Gate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-18 13:01:22

Jeśli # wpiszesz plik dwa razy w .pliki h niż kompilator da błąd. Ale jeśli # importujesz Plik więcej niż raz kompilator zignoruje go.

 1
Author: Husmukh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 09:43:02

W maju miałem zmienną globalną w jednym z moich plików .h, która powodowała problem, i rozwiązałem go dodając extern przed nim.

 1
Author: Winston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-10 15:47:32

#include używany do pobierania "rzeczy" z innego pliku do tego, w którym #include jest używany. Ex:

W pliku: main.cpp

#include "otherfile.h"

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

Osłona nagłówka jest używana na górze KAŻDEGO pliku nagłówka (*.h) aby zapobiec dołączaniu tego samego pliku więcej niż jeden raz (jeśli to się stanie, otrzymasz błędy kompilacji).

W pliku: otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif

Nawet jeśli umieścisz #include " otherfile.h " N czas w swoim kodzie, to wewnątrz niego nie zostanie ponownie zgłoszony.

 0
Author: Celso Dantas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 01:03:19