即使我只是更改局部私有变量,或更改局部范围(有时甚至是局部私有函数范围)中常量的值,Xcode 11也会重新编译(几乎?)我的整个项目。我有时可以通过快速构建获得2或3个更改,但是很快它决定再次重新编译所有内容(这需要很长时间)。
任何想法可能会发生什么?Xcode无法确定更改了什么,为什么还要重新编译很多其他内容(甚至其他模块)。
任何建议都非常感谢,谢谢!
即使我只是更改局部私有变量,或更改局部范围(有时甚至是局部私有函数范围)中常量的值,Xcode 11也会重新编译(几乎?)我的整个项目。我有时可以通过快速构建获得2或3个更改,但是很快它决定再次重新编译所有内容(这需要很长时间)。
任何想法可能会发生什么?Xcode无法确定更改了什么,为什么还要重新编译很多其他内容(甚至其他模块)。
任何建议都非常感谢,谢谢!
Answers:
我们遇到了同样的问题,并已解决。两次。
增量构建(相同的构建机器):
之前:〜10m之后:〜35s
让我们先从我们的经验开始。我们有一个庞大的Swift / Obj-C项目,这是主要的问题:构建时间很慢,您必须创建一个新项目以实现新功能(从字面上看)。永不起作用的语法突出显示的加分点。
要真正解决此问题,您必须真正了解构建系统的工作方式。例如,让我们尝试以下代码片段:
import FacebookSDK
import RxSwift
import PinLayout
并想象您在文件中使用了所有这些导入。而且此文件依赖于另一个文件,该文件依赖于另一个库,后者又使用另一个库等。
因此,要编译文件,Xcode必须编译您提到的每个库以及它依赖的每个文件,因此,如果更改其中一个“核心”文件,则Xcode必须重建整个项目。
Xcode构建是多线程的,但是它由许多单线程树组成。
因此,在每次增量构建的第一步中,Xcode都决定必须重新编译哪些文件并构建AST树。如果你改变它充当“文件可靠上的其他文件”,因此它充当“所有其他文件相关的 ”必须重新编译。
因此,第一个建议是降低耦合。您的项目部分必须彼此独立。
如果您使用的是Obj-C / Swift桥,则这些树会出现问题,Xcode必须经历比平常更多的阶段:
完美世界:
Obj-C / Swift桥:
因此,如果您从第1步或第2步中进行更改,则基本上会遇到麻烦。最好的解决方案是最小化Obj-C / Swift Bridge(并将其从项目中删除)。
如果您没有Obj-C / Swift桥,那就太好了,您可以继续下一步:
是时候使用SwiftPM了(或者至少可以更好地配置您的Cocoapods)。
事实是,大多数具有默认Cocoapods配置的框架会拖累许多您不需要的东西。
要对此进行测试,请创建一个仅具有一个依赖项(例如PinLayout)的空项目,然后尝试使用Cocoapods(默认配置)和SwiftPM编写此代码。
import PinLayout
final class TestViewController: UIViewController {
}
剧透:Cocoapods将编译此代码,因为Cocoapods将导入PinLayout的每个导入(包括UIKit),而SwiftPM则不会,因为SwiftPM原子地导入框架。
您还记得Xcode构建是多线程的吗?
好吧,如果您能够将项目拆分成许多独立的部分并将它们作为独立的框架导入到项目中,则可以滥用它。它确实降低了耦合,这实际上是我们使用的第一个解决方案,但实际上效果不是很好,因为我们只能将增量构建时间减少到〜4-5m,与第一种方法相比,这没什么。
这里没有金色的子弹,但是有很多事情需要检查:
如果您使用的是RxSwift之类的类型推断繁重框架,则添加显式类型注释可以加快构建时间。
如果项目很大,您可以考虑将源文件的逻辑组重构到框架中,但这可能比您想的要大得多
如果您提供了有关该项目的更多详细信息,则可能会有所帮助:是否静态链接任何库?它是框架还是应用程序目标?您使用的是多大版本和哪个版本?您是否有某些自定义的构建阶段,例如linters或代码生成,有时会被跳过?