ric*_*ter 32
不,但你不需要它 - import UIKit超过你输入12个字符的时间是没有成本的.(或者使用已经存在它们的Xcode新文件模板.)
这是TLDR.对于整个故事,请继续阅读......
在(Obj)C中,使API可用于源代码文件的旧方法是文本包含.预处理器会看到你的#import <Foundation/Foundation.h>指令并将该头文件中的所有文本(以及它包含的任何其他头文件,以及它们包含的头文件等等)复制到源文件中,然后再将其传递给编译器.正如您所料,为项目中的每个文件重新编译数千行系统头声明并不是那么高效.
因此,我们在几年前获得了预编译头文件 - 您将常用文件#import放在一个位置,这些部件的编译步骤将完成一次,结果是编译器后端可以重用于项目中的每个文件.但这也存在问题:保持PCH满意是一种维护负担,并且它不允许您限制每个源文件中使用的命名空间(即,如果您希望.m项目中的一个文件只看到它需要的符号使用,而不是项目中其他地方使用的所有其他东西).
最重要的是,文本包含具有潜在的脆弱性问题.如果你#define的#import行以上的东西,并且定义更改了导入标题中使用的符号,那些标题将有编译错误(或以更微妙的方式失败,如定义错误的API).有些惯例可以防止这种情况发生,但是约定并没有强制执行 - 你总是一个错字/新的团队成员/糟糕的合并,远离一切分崩离析.
无论如何,即使使用预编译的头文件,文本包含也不是很好,所以在Xcode 5 Apple中引入了模块.(实际上,不只是Apple.他们在LLVM/Clang编译器套件中,因此它们是开源的.)模块基于语义导入,而不是文本包含 - 也就是说,模块在抽象层面告诉编译器什么它使源代码可用的API符号,而不是粘贴在这些符号的定义文本中 - 因此它们不易碎,并且它们在后端单独预编译,因此构建项目的速度很快.
模块现在是ObjC项目的默认模块.(请注意,如果您创建一个新的ObjC项目,它不再包含预编译的头.您可以关闭模块,所以如果您有一个旧项目,您可能仍然使用文本包含和预编译头.)您可以找到更多关于WWDC 2013会话404中的 ObjC模块.
为什么关于ObjC的所有这些业务?我们正在谈论斯威夫特,对吧?好吧,Swift基于很多相同的基础设施.
Swift从一开始就使用模块,所以它始终基于语义导入.这意味着没有构建时间性能,也没有脆弱性.Swift import所做的就是告诉编译器你需要什么符号(以及链接器在生成二进制可执行文件时在哪里找到它们).
因此,将相同的imports放在每个文件顶部的唯一成本是打字.这是一个必要的成本 - 在Swift中,源文件是一个语义单元,确定进入它的内容具有真正的意义.例如,如果您import Foundation要启用与Cocoa集合和值类型的桥接,许多Swift标准库类型的行为都会发生变化- 如果您的应用程序的某个部分想要严格使用Swift集合和值类型,您可能不需要导入Foundation(或Cocoa或UIKit或包含它的其他东西).
更新:此外,您import在Swift文件中选择的内容具有实际意义.
例如,编译器如何优化泛型和静态/动态分派取决于给定文件中可见的声明,因此如果import您需要的更多,则可能会生成更慢的代码.所以一般来说,最好import只满足你的需求.
显式导入还有助于提高清晰度和可读性.如果imports是项目范围的,那么当你将代码从一个项目复制粘贴到另一个项目中时,你会在新位置看到很多错误...而且import你需要解决的问题要清楚得多他们.
"但我讨厌把import所有的文件放在每个文件的顶部,"你说.让我们考虑一下.
你真的需要几个吗?大多数模块都是传递import它们的依赖关系.import Foundation如果你已经在使用importCocoa(OS X)或UIKit(iOS/tvOS/watchOS),则不需要.例如,如果您正在编写SpriteKit或SceneKit游戏,您将自动获得UIKit/Cocoa(适用于任何平台)和Foundation.
你真的需要在每个档案中都一样吗?当然,你在UIKit项目中,所以你几乎到处都在使用UIKit.但这只是import顶部的十二个字符.也许您的项目也使用了Contacts或Photos或CoreBluetooth或HealthKit ......但它可能不需要在您定义的每种类型中使用所有这些.(如果确实如此,您的代码可能会受到关注点分离不良的影响.)
你真的管理import报表所有的时间?我不知道你的项目,但在我参与的大多数大型项目中,我认为至少90%的开发活动涉及编辑现有的源文件,而不是创建新文件......在开始项目工作之后或者主要功能,我们很少(重新)定义源文件集或其依赖项.还有一些快捷方式可以帮助(除其他外)设置导入,比如Xcode文件模板.
jqg*_*imo 19
创建Objective-C桥接头文件:
[新文件→iOS→源→头文件]:
Bridging-Header.h
转到此新标头并导入外部库:
@import Module1Name;
@import Module2Name;
...
Run Code Online (Sandbox Code Playgroud)转到Build Settings,设置Objective-C Bridging Header的路径:
[目标→构建设置→Swift编译器 - 代码生成→Objective-C桥接头]:
$(SRCROOT)/.../Bridging-Header.h
然后,您可以在没有import代码的每个文件中使用外部库.
参考文献: