模块是为大多数Apple框架(UIKit、MapKit、GameKit等)预先构建的。您可以在自己创建的框架中使用它们:如果你在Xcode中创建Swift框架,它们会自动创建,你也可以为any Apple or 3rd-party library手动创建一个“.modulemap”文件。 您可以使用代码完成来查看可用框架的列表:
//previously
run into dependency -> compile dependency
run into dependency -> compile dependency
//@import
compile dependency
run into dependency -> load compiled binary
run into dependency -> load compiled binary
Enable Modules(C and Objective-C)(CLANG_ENABLE_MODULES)-CLANG #include, #import指令会自动转换为@import,这将带来所有优势。Modulemap允许无缝转换,因为它包含头文件和子/模块之间的Map 通过-fmodules
#include, #import -> @import
Link Frameworks Automatically(CLANG_MODULES_AUTOLINK)-启用系统模块自动链接。需要激活的CLANG_ENABLE_MODULES。自动链接允许基于#import, @import(Objective-C), import(Swift)传递-framework <framework_name> 如果否-通过-fno-autolink标志
模块启动声响==否和模块自动链接声响==否**
如果要处理系统(#import <UIKit/UIKit.h>)链接手动(而不是自动链接),则有两种变体: 1.将依赖项添加到General -> Frameworks and Libraries or Frameworks, Libraries, and Embedded Content
Build Settings -> Other Linker Flags(OTHER_LDFLAGS) -> -framework <module_name>
在以下情况下将引发下一个错误:
Undefined symbol: _OBJC_CLASS_$_UIView
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_UIView", referenced from:
objc-class-ref in ClassB.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
6条答案
按热度按时间0s7z1bwu1#
这是一个名为模块或“语义导入”的新功能。关于205和404会话的WWDC 2013视频中有更多信息。这是一种更好的预编译头文件实现。您可以在iOS 7和Mavericks中的任何系统框架中使用模块。模块是框架可执行文件及其头文件的打包,被吹捧为比
#import
更安全、更高效。使用
@import
的一大优势是你不需要在项目设置中添加框架,它是自动完成的。这意味着你可以跳过点击加号按钮并搜索框架(黄金工具箱)的步骤,然后将其移动到“Frameworks”组。这将使许多开发人员避免收到神秘的“Linker error”消息。**您实际上不需要使用
@import
关键字。**如果您选择使用模块,则所有#import
和#include
指令都将Map为自动使用@import
。这意味着您不必更改源代码(或者从其他地方下载的库的源代码)。据说使用模块也可以提高构建性能,特别是在您没有很好地使用PCH或者您的项目有很多小的源文件的情况下。模块是为大多数Apple框架(UIKit、MapKit、GameKit等)预先构建的。您可以在自己创建的框架中使用它们:如果你在Xcode中创建Swift框架,它们会自动创建,你也可以为any Apple or 3rd-party library手动创建一个“.modulemap”文件。
您可以使用代码完成来查看可用框架的列表:
在Xcode 5的新项目中默认启用模块。要在旧项目中启用它们,请进入项目构建设置,搜索“Modules”并将“Enable Modules”设置为“YES”。“Link Frameworks”也应设置为“YES”:
你必须使用Xcode 5和iOS 7或Mavericks SDK,但你仍然可以发布旧操作系统(比如iOS 4.3或其他)。模块不会改变你的代码构建方式或任何源代码。
来自WWDC幻灯片:
#define readonly 0x01
)的影响显式使用模块:
将
#import <Cocoa/Cocoa.h>
替换为@import Cocoa;
您也可以使用以下符号仅导入一个标题:
在Xcode中,子模块会自动完成。
cnwbcb6i2#
你可以在《用Objective-C学习可可(ISBN:(电话:978-1-491- 90一三九-7)
模块是一种将文件和库包含并链接到项目中的新方法。要理解模块的工作原理及其优点,回顾Objective-C和#import语句的历史是很重要的。无论何时,当你想包含一个文件以供使用时,你通常会有一些代码,看起来像这样:
或者在框架的情况下:
因为Objective-C是C语言的超集,所以#import语句是C的
#include
语句的一个小的改进。编译时,它会将包含文件中的所有内容复制到代码中。2这有时会导致严重的问题。3例如,假设你有两个头文件:SomeFileA.h
和SomeFileB.h
;SomeFileA.h
包含SomeFileB.h
,而SomeFileB.h
包含SomeFileA.h
。这会产生一个循环,并且会使coimpiler混淆。为了处理这个问题,C程序员必须编写防止这种事件发生的保护措施。当使用
#import
时,你不需要担心这个问题,也不需要写头文件来避免它。然而,#import
仍然只是一个美化了的复制粘贴操作,会导致编译时间变慢,还有许多其他较小但仍然非常危险的问题(比如包含的文件覆盖了你在代码中声明的内容)。模块是一种尝试。它们不再是复制粘贴到源代码中,而是包含的文件的序列化表示,只有在需要的时候才能导入到源代码中。使用模块,代码通常会编译得更快,比使用#include或
#import
更安全。返回到前面导入框架的示例:
要将此库作为模块导入,代码应更改为:
Xcode的另一个好处是可以自动将SomeLibrary框架链接到项目中。模块也允许你只将你真正需要的组件包含到项目中。例如,如果你想使用AwesomeLibrary框架中的AwesomeObject组件,通常你必须导入所有组件才能使用其中的一部分。然而,使用模块,你可以只导入你想使用的特定对象:
对于所有在Xcode 5中创建的新项目,默认情况下模块是启用的。如果你想在旧项目中使用模块(你真的应该),它们必须在项目的构建设置中启用。一旦你做到了这一点,你就可以在代码中同时使用
#import
和@import
语句了。5t7ly7z53#
而不是使用通常模块
#include -> #import(https://stackoverflow.com/a/59212007/4770877)-〉Precompiled Headers .pch(https://stackoverflow.com/a/59213256/4770877)-〉@导入模块(对象C); - 〉import Module(Swift)(https://stackoverflow.com/a/67130959/4770877)
它是LLVM Modules的一部分
@import <module_name>;
声明指示编译器加载(而不是编译)模块的预编译二进制文件,这减少了生成时间。以前编译器每次运行时都会编译依赖项,但现在应该提前编译并加载依赖项Modulemap(https://stackoverflow.com/a/59213694/4770877)-模块和接头之间的桥接
Enable Modules(C and Objective-C)(CLANG_ENABLE_MODULES)
-CLANG#include, #import
指令会自动转换为@import
,这将带来所有优势。Modulemap
允许无缝转换,因为它包含头文件和子/模块之间的Map通过
-fmodules
Link Frameworks Automatically(CLANG_MODULES_AUTOLINK)
-启用系统模块自动链接。需要激活的CLANG_ENABLE_MODULES
。自动链接允许基于#import, @import(Objective-C), import(Swift)
传递-framework <framework_name>
如果否-通过
-fno-autolink
标志如果要处理系统(
#import <UIKit/UIKit.h>
)链接手动(而不是自动链接),则有两种变体:1.将依赖项添加到
General -> Frameworks and Libraries or Frameworks, Libraries, and Embedded Content
Build Settings -> Other Linker Flags(OTHER_LDFLAGS) -> -framework <module_name>
在以下情况下将引发下一个错误:
CLANG_ENABLE_MODULES
已禁用CLANG_MODULES_AUTOLINK
被禁用,并且没有手动链接7y4bm7vi4#
它目前只适用于内置的系统框架。如果你像苹果一样使用
#import
,仍然在应用程序委托中导入UIKit
框架,它会被替换(如果modules是打开的,并且它被识别为系统框架),编译器会将它重新Map为模块导入,而不是头文件的导入。因此,无论如何,保留#import
与将其转换为模块导入是一样的4ngedf3f5#
似乎自XCode 7.x以来,在使用
CLANG_ENABLE_MODULES
启用clang模块时出现了大量警告看一看Lots of warnings when building with Xcode 7 with 3rd party libraries
nsc4cvqm6#
使用模块有几个好处。你只能在苹果的框架中使用它,除非创建了模块Map。
@import
有点类似于预编译头文件,当添加到.pch
文件时,这是一种调整应用程序编译过程的方法。此外,你不必以旧的方式添加库,事实上,使用@import
要快得多,效率也高得多。如果你还在寻找一本不错的参考书,我强烈推荐你阅读this article。