@import使用

来源:互联网 发布:mysql 修改列字符集 编辑:程序博客网 时间:2024/05/21 19:43

在xcode 5 下,为了更易于开发,增加了modules和 auto-linking 这两个新特性。用 @import 来增加框架 到项目中比用 #import会更有效. 我们来看看为什么:

“Modules for system frameworks speed build time and provide an alternate means to import APIs from the SDK instead of using the C preprocessor. Modules provide many of the build-time improvements of precompiled headers with less maintenance or need for optimization. They are designed for easy adoption with little or no source changes. Beyond build-time improvements, modules provide a cleaner API model that enables many great features in the tools, such as Auto Linking.”

大概意思:Modules为系统框架加快了构建时间,并且提供了一个方法从SDK导入APIs,以此代替c预编译。Modules使预编译头文件的可以较少的维护和较少的优化,因此加快了构建时间。他们被设计的使用起来很简单,使用时很少或者没有资源的变化。除了构建时间的加速,Modules提供了一个很干净的API模型,通过一些工具,例如:AutoLining,可以具有很多特性。

Modules and auto-linking 默认情况下是enabled的。 如果是旧的项目,你可以通过设置”Language - Modules.” 来设置Enable Modules 和Link Frameworks Automatically 为Yes。

另外一个使用moudules的好处是你再也不用去链接你的framework到你的项目了。

例如,在以前,如果你要使用MapKit这个框架,你要这样做
1) 使用语句 #import < FrameworkFoo/HeaderBar.h > 导入框架
2) 去到项目的build phases 设置项,找 到FrameworkFoo.framework.并加入到Link Binary With Libraries里面。

如果使用modules的话,只需要加入语句 @import FrameworkFoo; 你就可以开始使用了,根本不需要链接到你的项目。

什么是Modules呢?

首先先看看#include 与 #import的区别:

 共同点:将目标.h文件中的内容一字不落地拷贝到当前文件中,并替换掉这句include(或者import) 不同点:(1)#import:保证每个头文件只会被引用一次,避免重复引用可能带来的编译错误.(2)#include:不能保证只被引用一次.import代码演示: #ifndef 一个标志#define 一个标志#endif

include做的事情其实就是简单的复制粘贴,将目标.h文件中的内容一字不落地拷贝到当前文件中,并替换掉这句include,而#import实质上做的事情和#include是一样的,只不过OC为了避免重复引用可能带来的编译错误,而加入了#import,从而保证每个头文件只会被引用一次。
如果想深究,import的实现是通过#ifndef一个标志进行判断,然后在引入后#define这个标志,来避免重复引用的

实质上import也还是拷贝粘贴,这样就带来一个问题:当引用关系很复杂,或者一个头文件被非常多的实现文件引用时,编译时引用所占的代码量就会大幅上升(因为被引用的头文件在各个地方都被copy了一遍)。为了解决这个问题,C系语言引入了预编译头文件(PreCompiled Header),将公用的头文件放入预编译头文件中预先进行编译,然后在真正编译工程时再将预先编译好的产物加入到所有待编译的Source中去,来加快编译速度。比如iOS开发中Supporting Files组内的.pch文件就是一个预编译头文件,默认情况下,它引用了UIKit和Foundation两个头文件–这是在iOS开发中基本每个实现文件都会用到的东西。

于是理论上说,想要提高编译速度,可以把所有头文件引用都放到pch中。但是这样面临的问题是在工程中随处可用不应该访问的东西,而编译器也无法准确给出错误或者警告,无形中增加了出错的可能性。

于是Modules诞生了。Modules相当于将框架进行了封装,然后加入在实际编译之时加入了一个用来存放已编译添加过的Modules列表。如果在编译的文件中引用到某个Modules的话,将首先在这个列表内查找,找到的话说明已经被加载过则直接使用已有的,如果没有找到,则把引用的头文件编译后加入到这个表中。这样被引用到的Modules只会被编译一次,但是在开发时又不会被意外使用到,从而同时解决了编译时间和引用泛滥两方面的问题。

稍微追根问底,Modules是什么?其实无非是对框架进行了如下封装,拿UIKit为例:

framework module UIKit {     umbrella header "UIKit.h" module * {export *}link framework "UIKit" } 

这个Module定义了首要头文件(UIKit.h),需要导出的子modules(所有),以及需要link的框架名称(UIKit)。需要指出的是,现在Module还不支持第三方的框架,所以只有SDK内置的框架能够从这个特性中受益。另外,在C++的源代码中,Modules也是被禁用的。

Autolinking是Modules的附赠小惊喜,因为在module定义的时候指定来link framework,所以在编译module时LLVM会将所涉及到的框架自动帮你写到link里去,不再需要到编译设置里去添加了。

Modules和Autolinking

1 0
原创粉丝点击