@import vs #import – iOS 7

我正在玩弄一些新的iOS 7function,并使用WWDCvideo“实现在iOS上使用UI”中讨论的一些图像效果。 为了在会话的源代码中产生模糊效果, UIImage通过导入UIKit的类来扩展,如下所示:

 @import UIKit; 

我想我在另一个会话video中看到了这个,但是我很难find它。 我在找什么时候使用这个背景资料。 它只能用于苹果框架? 使用这个编译器指令的好处,我应该回去和更新旧的代码?

这是一个称为模块或“语义导入”的新function。 第二百零五节和第四十四节的WWDC 2013video中有更多信息。 这是预编译头文件的更好的实现。 您可以将模块与iOS 7和Mavericks中的任何系统框架一起使用。 模块是框架可执行文件和头文件的封装,被吹捧为比#import更安全,更高效。

使用@import最大的好处之一就是你不需要在项目设置中添加框架,它是自动完成的 。 这意味着您可以跳过单击加号button并search框架(金色工具箱)的步骤,然后将其移至“框架”组。 这将节省许多开发人员的神秘“链接器错误”消息。

您实际上不需要使用@import关键字。 如果您select使用模块,则所有#import#include指令都将被映射为自动使用@import 。 这意味着您不必更改源代码(或从其他位置下载的库的源代码)。 假设使用模块也会提高构build性能,特别是如果您没有使用PCH,或者您的项目有许多小的源文件。

模块是为大多数苹果框架(UIKit,MapKit,GameKit等)预先构build的。 你可以在自己创build的框架中使用它们:如果你在Xcode中创build一个Swift框架,它们会自动创build,你可以手动为任何Apple或者第三方库创build一个“.modulemap”文件。

您可以使用代码完成来查看可用框架的列表:

在这里输入图像描述

在Xcode 5的新项目中默认启用模块 。 要在较旧的项目中启用它们,请进入项目构build设置,search“模块”并将“启用模块”设置为“是”。 “链接框架”也应该是“是”:

你必须使用Xcode 5和iOS 7或者Mavericks SDK,但是你仍然可以发布老版本的操作系统(比如iOS 4.3或者其他)。 模块不会改变您的代码的构build方式或任何源代码。


从WWDC幻灯片:

  • 导入框架的完整语义描述
  • 不需要parsing标题
  • 导入框架界面的更好方法
  • 加载二进制表示
  • 比预编译头更灵活
  • 免受本地macros定义的影响(例如#define readonly 0x01
  • 默认为新项目启用

要明确使用模块:

@import Cocoa;replace#import <Cocoa/Cocoa.h> @import Cocoa;

您也可以用这个表示法只导入一个标题:

 @import iAd.ADBannerView; 

Xcode中的子模块自动完成。

好的答案,你可以在书中学习cocoa与Objective-C(ISBN:978-1-491-90139-7)

模块是一种将文件和库链接到项目中的新方法。 为了理解模块是如何工作的,以及它们有什么好处,回顾Objective-C和#import语句的历史是非常重要的。每当你想包含一个文件以供使用时,你通常会看到如下代码:

 #import "someFile.h" 

或者在框架的情况下:

 #import <SomeLibrary/SomeFile.h> 

由于Objective-C是C编程语言的超集,因此#incport语句对#import语句是一个小小的改进。 #include语句非常简单; 它会在编译过程中将包含文件中的所有内容复制到您的代码中。 这有时会导致重大问题。 例如,假设你有两个头文件: SomeFileA.hSomeFileB.h ; SomeFileA.h包含SomeFileB.hSomeFileB.h包含SomeFileA.h 。 这会创build一个循环,并可以混淆coimpiler。 为了解决这个问题,C程序员必须防范这类事件的发生。

当使用#import ,你不需要担心这个问题,或者编写头文件来避免它。 然而, #import仍然只是一个优化的复制粘贴操作,导致其他一些较小但仍然非常危险的问题(如包含的文件覆盖您已在其他代码中声明的某些内容)的编译时间较慢。

模块是试图解决这个问题。 它们不再是对源代码的复制和粘贴,而是包含文件的序列化表示,只有在需要时才能将其导入到源代码中。 通过使用模块,代码通常会更快地编译,比使用#include或#import更安全。

回到之前导入框架的例子:

 #import <SomeLibrary/SomeFile.h> 

要将该库作为模块导入,代码将更改为:

 @import SomeLibrary; 

这有Xcode额外的好处,将SomeLibrary框架自动链接到项目中。 模块还允许您只将真正需要的组件包含到项目中。 例如,如果你想在AwesomeLibrary框架中使用AwesomeObject组件,通常你将不得不导入所有东西来使用它。 但是,使用模块,您可以导入要使用的特定对象:

 @import AwesomeLibrary.AwesomeObject; 

对于在Xcode 5中创build的所有新项目,默认情况下启用模块。 如果您想在较旧的项目中使用模块(而且您确实应该),则必须在项目的构build设置中启用它们。 一旦你这样做,你可以在你的代码中同时使用#import@import语句,而不用担心。

它目前只适用于内置的系统框架。 如果你使用#import像苹果仍然在应用程序委托中导入UIKit框架,它会被replace(如果模块处于打开状态并且它被识别为系统框架),编译器将重映射为模块导入,而不是导入无论如何,头文件。 所以,如果可能的话,留下#import就和它转换成模块导入一样

看来,由于XCode 7.x很多警告出来时启用铛模块与CLANG_ENABLE_MODULES

看看使用第三方库编译Xcode 7时的许多警告

使用模块有一些好处。 除非创build模块映射,否则只能在Apple的框架中使用它。 @import被添加到.pch文件时,有点类似于预编译头文件,这是一种调整应用程序编译过程的方式。 此外,您不必以旧的方式添加库,使用@import实际上更快更高效。 如果你仍然期待一个很好的参考,我会强烈推荐你阅读这篇文章 。