@import vs #import - iOS 7


432

Sto giocando con alcune delle nuove funzionalità di iOS 7 e sto lavorando con alcuni degli effetti di immagine come discusso nel video del WWDC "Implementazione di Engaging UI su iOS". Per produrre un effetto di sfocatura all'interno del codice sorgente per la sessione, è UIImagestato esteso tramite una categoria che importa UIKit in questo modo:

@import UIKit;

Penso di aver visto qualcosa al riguardo in un altro video di sessione, ma ho problemi a trovarlo. Sto cercando informazioni di base su quando utilizzarlo. Può essere utilizzato solo con i framework Apple? I vantaggi dell'utilizzo di questa direttiva del compilatore sono sufficienti per poter tornare indietro e aggiornare il vecchio codice?


Risposte:


838

È una nuova funzionalità chiamata Moduli o "importazione semantica". Ci sono maggiori informazioni nei video del WWDC 2013 per le sessioni 205 e 404 . È una specie di migliore implementazione delle intestazioni precompilate. Puoi utilizzare i moduli con qualsiasi framework di sistema in iOS 7 e Mavericks. I moduli sono un insieme dell'eseguibile del framework e delle sue intestazioni e sono considerati più sicuri ed efficienti di #import.

Uno dei grandi vantaggi dell'utilizzo @importè che non è necessario aggiungere il framework nelle impostazioni del progetto, è fatto automaticamente . Ciò significa che puoi saltare il passaggio in cui fai clic sul pulsante più e cercare il framework (casella degli strumenti d'oro), quindi spostarlo nel gruppo "Frameworks". Salverà molti sviluppatori dai messaggi criptici di "errore Linker".

In realtà non è necessario utilizzare la @importparola chiave. Se si sceglie di utilizzare i moduli, tutte #importe le #includedirettive vengono mappate per l'uso @importautomatico. Ciò significa che non è necessario modificare il codice sorgente (o il codice sorgente delle librerie che si scarica da altrove). Presumibilmente l'uso dei moduli migliora anche le prestazioni di compilazione, soprattutto se non si utilizzano bene i PCH o se il progetto ha molti piccoli file di origine.

I moduli sono pre-costruiti per la maggior parte dei framework Apple (UIKit, MapKit, GameKit, ecc.). Puoi usarli con i framework che crei tu stesso: vengono creati automaticamente se crei un framework Swift in Xcode e puoi creare manualmente un file ".modulemap" per qualsiasi libreria Apple o di terze parti .

È possibile utilizzare il completamento del codice per visualizzare l'elenco dei framework disponibili:

inserisci qui la descrizione dell'immagine

I moduli sono abilitati per impostazione predefinita nei nuovi progetti in Xcode 5 . Per abilitarli in un progetto precedente, vai nelle impostazioni di creazione del progetto, cerca "Moduli" e imposta "Abilita moduli" su "SÌ". Anche "Link Frameworks" dovrebbe essere "SÌ":

Devi usare Xcode 5 e iOS 7 o Mavericks SDK, ma puoi comunque rilasciarlo per sistemi operativi più vecchi (ad esempio iOS 4.3 o altro). I moduli non cambiano la modalità di creazione del codice o di alcun codice sorgente.


Dalle diapositive del WWDC:

  • Importa una descrizione semantica completa di un framework
  • Non ha bisogno di analizzare le intestazioni
  • Modo migliore per importare l'interfaccia di un framework
  • Carica la rappresentazione binaria
  • Più flessibile delle intestazioni precompilate
  • Immunità agli effetti delle macro definizioni locali (ad es. #define readonly 0x01)
  • Abilitato per nuovi progetti per impostazione predefinita

Per usare esplicitamente i moduli:

Sostituisci #import <Cocoa/Cocoa.h>con@import Cocoa;

Puoi anche importare solo un'intestazione con questa notazione:

@import iAd.ADBannerView;

I sottomoduli vengono completati automaticamente in Xcode.


15
@DaveDeLong & Klaas: grazie! Devo ammettere che non sapevo nulla dei moduli quando ho risposto per la prima volta. Sono andato a vedere la Sessione 404 per impararla. La presentazione che ha dato Doug Gregor (il ragazzo LLVM) è stata davvero ben fatta. C'è anche una discussione sui moduli C ++ in cui vengono spiegati i vantaggi qui: youtube.com/watch?v=4Xo9iH5VLQ0
re nevan

3
@ nevan-- grazie per la risposta. Volevo solo aggiungere che al momento i moduli non supportano terze parti e i tuoi framework.
jamdaddy25,

Puoi usarlo per le tue lezioni?
cfischer,

5
Penso che dovresti essere in grado di importare framework di terze parti se viene fornito un module.map appropriato. La documentazione del modulo clang LLVM: clang.llvm.org/docs/Modules.html#module-map-language
bames53

1
Oh, in realtà sembra che abbia @import sqlite3funzionato per me perché avevo creato il mio module.map per esso e quando ho capito che sqlite era incluso in OS X e ho rimosso il mio module.map, il compilatore ha continuato a utilizzare il modulo obsoleto.
bames53

46

Bella risposta che puoi trovare nel libro Learning Cocoa con Objective-C (ISBN: 978-1-491-90139-7)

I moduli sono un nuovo mezzo per includere e collegare file e librerie nei tuoi progetti. Per capire come funzionano i moduli e quali vantaggi hanno, è importante guardare indietro alla storia di Objective-C e la dichiarazione #import Ogni volta che si desidera includere un file da utilizzare, in genere si avrà un codice simile al seguente:

#import "someFile.h"

O nel caso di quadri:

#import <SomeLibrary/SomeFile.h>

Poiché Objective-C è un superset del linguaggio di programmazione C, l' #includeaffermazione #import è un raffinamento minore sull'affermazione di C. L'affermazione #include è molto semplice; copia tutto ciò che trova nel file incluso nel codice durante la compilazione. Questo a volte può causare problemi significativi. Ad esempio, immagina di avere due file di intestazione: SomeFileA.he SomeFileB.h; SomeFileA.hinclude SomeFileB.he SomeFileB.hinclude SomeFileA.h. Questo crea un ciclo e può confondere il coimpiler. Per far fronte a questo, i programmatori C devono scrivere protezioni contro questo tipo di evento.

Durante l'utilizzo #import, non è necessario preoccuparsi di questo problema o scrivere le protezioni delle intestazioni per evitarlo. Tuttavia, #importè ancora solo un'azione glorificata di copia e incolla, che causa tempi di compilazione lenti tra una serie di altri problemi più piccoli ma ancora molto pericolosi (come un file incluso che sostituisce qualcosa che hai dichiarato altrove nel tuo codice).

I moduli sono un tentativo di aggirare questo. Non sono più una copia e incolla nel codice sorgente, ma una rappresentazione serializzata dei file inclusi che possono essere importati nel codice sorgente solo quando e dove sono necessari. Usando i moduli, il codice generalmente si compila più velocemente ed è più sicuro dell'uso di #include o #import.

Tornando all'esempio precedente di importazione di un framework:

#import <SomeLibrary/SomeFile.h>

Per importare questa libreria come modulo, il codice verrebbe modificato in:

@import SomeLibrary;

Questo ha l'ulteriore vantaggio di Xcode che collega automaticamente il framework SomeLibrary al progetto. I moduli ti consentono anche di includere solo i componenti di cui hai veramente bisogno nel tuo progetto. Ad esempio, se si desidera utilizzare il componente AwesomeObject nel framework AwesomeLibrary, normalmente è necessario importare tutto solo per utilizzare il pezzo unico. Tuttavia, utilizzando i moduli, puoi semplicemente importare l'oggetto specifico che desideri utilizzare:

@import AwesomeLibrary.AwesomeObject;

Per tutti i nuovi progetti realizzati in Xcode 5, i moduli sono abilitati per impostazione predefinita. Se vuoi usare i moduli in progetti più vecchi (e dovresti davvero) dovranno essere abilitati nelle impostazioni di compilazione del progetto. Una volta che lo fai, puoi usare entrambe #importe le @importistruzioni nel tuo codice insieme senza alcuna preoccupazione.


Non c'è alcuna opzione nel mio progetto (Xcode 6) che ho iniziato su Xcode 4 per abilitare i moduli. Posso aggiungerlo manualmente in qualche modo?
Fantastico -11

Build target is iOS 6, penso che questo sia il problema
Awesome-o

4

Attualmente funziona solo per i framework di sistema integrati. Se usi #importcome apple continui a importare il UIKitframework nel delegato dell'app, viene sostituito (se i moduli sono attivi e riconosciuto come framework di sistema) e il compilatore lo rimappa in modo da essere un modulo di importazione e non un'importazione dei file di intestazione . Quindi lasciare il #importsarà lo stesso del suo convertito in un modulo di importazione, ove possibile



1

Vi sono alcuni vantaggi dell'utilizzo dei moduli. Puoi usarlo solo con il framework Apple a meno che non venga creata la mappa dei moduli. @importè un po 'simile ai file delle intestazioni pre-compilati quando aggiunti al .pchfile, il che è un modo per ottimizzare l'app durante il processo di compilazione. Inoltre, non è necessario aggiungere librerie alla vecchia maniera, infatti l'utilizzo @importè molto più veloce ed efficiente. Se cerchi ancora un bel riferimento, ti consiglio vivamente di leggere questo articolo .


0

Storia:

#include => #import => .pch => @import

#include vs #import
.pch - Intestazione precompilata

Modulo - @import

Product Name == Product Module Name 

@modulela dichiarazione dice al compilatore di caricare un binario precompilato di framework che riduce un tempo di costruzione . Il framework modulare contiene .modulemap[Informazioni]

Se la funzione del modulo è abilitata nel progetto Xcode #includee le #importdirettive vengono convertite automaticamente in @importquesto porta tutti i vantaggi

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.