【问题标题】:How to handle large Swift Project?如何处理大型 Swift 项目?
【发布时间】:2015-03-17 22:09:48
【问题描述】:

在我用 Swift 编写的 iPhone 应用程序变得相当大(> 150 个 .swift 文件 + 各种 Objective-C 库)之后,Xcode 开始表现得很糟糕:

  • 每第二次编译我都会遇到各种错误,例如:

    Command failed due to signal: Segmentation fault: 11

  • 编译需要大量时间(在 MacBook Pro Retina 上 > 2 分钟)
  • 等等。

我只是想知道是否每个人都有同样的问题,也许有人找到了减少这种噩梦的方法?

到目前为止我所做的——我将项目拆分为几个动态框架,我从主项目链接到这些框架,这有助于减少编译时间,但引入了一些新问题。

我还使用 iRamDisk 将 DerivedData 文件夹保留在 RAM 中并定期从中删除所有文件,这有时有助于解决 SourceKit 崩溃问题。

【问题讨论】:

  • 和我一起工作的一个人正在做一个大型的 Swift 项目,并且遇到了一些类似的困难。无论如何,他最终使用了与您相同的解决方案。
  • 和你在同一条船上。对于我和我团队中的其他人来说,让我们抓狂的是源工具包崩溃。
  • 动态框架是你最好的盟友恕我直言。只要它们是通用的(对于模拟器和设备),应该不会出现什么问题。
  • 分段错误可能是由于在扩展中引用了函数。
  • 这类问题真的让我觉得 Swift 还没有完全成熟。最好在烤箱里多放一会儿。

标签: ios xcode swift compilation


【解决方案1】:

你可以试试:

  • 升级计算机中的 RAM 容量
  • 如果您有多个 .swift 文件在同一个视图控制器上执行操作,请尝试将它们压缩为每个视图控制器一个 .swift 文件
  • 调整编译源下的设置以查看是否有任何重复项,或者是否可以添加任何脚本或设置以使其编译更快...

您还可以查看this 帖子的答案,了解可以采取哪些措施来减慢编译时间

【讨论】:

  • 谢谢。我确实有 2013 年末 8Gb 的 MacBook Pro,因此无法升级 RAM。我不确定另外 8-16Gb 是否会对购买新计算机产生很大影响。文件数量是否起重要作用?如果我将几个类放在一个文件中会更快吗?会尝试对其进行一些测试。
  • 我怀疑归档会消除差异。我认为主要是导入语句/对其他文件的引用、文件数量和设置。
【解决方案2】:

Apple 在Technical Note 2190 中提供了一些加快 Xcode 构建速度的建议。您是否考虑过 creating and precompiling an own framework 外包未更改的 Swift 模块或部分/全部 Objective-C 代码?

删除 Swift 中的所有类型推断。

This SO topic 有一些好主意,这个blog post 建议

  1. 停止生成 dSYM 包并
  2. 如果使用 Clang,请避免使用 -O4 进行编译。

虽然其中很多改进都与 Objective-C 相关,但我很确定其中一些仍然与 Swift 相关。

【讨论】:

  • “我很确定,其中一些仍然与 Swift 相关。”我不确定。 Swift 没有预编译之类的东西,而减慢 Swift 编译速度的东西是 Swift 独有的。举个简单的例子,仅仅有很多字符串“加法”就可以让编译崩溃。
  • 感谢您的评论。以前不知道 dSYM,这是一个好点。关于框架 - 我现在就是这样做的,这有一些问题,因为项目还处于早期阶段,我没有太多不需要经常更改的代码。现在我尝试以更模块化的方式重组项目。
  • 当你说类型推断时,你的意思是写 var s2:String = "A string" 比 var s = "A string" 好?
  • 关于构建速度,是的。
【解决方案3】:

(重新)编译是一个已知问题,我相信很快就会解决。一些建议:

  • 尽可能使用 Objective C - 即使它是 Swift 项目的一部分,它也能快速编译
  • 将代码拆分为框架
  • 指定类型,而不是让编译器来推断它们

同样,这个问题很有可能很快就会得到解决,所以此时最好不要在重写或重组代码方面进行大量投资。

【讨论】:

  • "Use Objective C" 我发布这个问题是为了避免这种情况,我真的很喜欢 Swift 并且希望至少稍微改进一下整体流程,而不是用 Objective C 编写代码。“指定类型" - 有道理,但代码变得不那么干净了。将尝试测试它会带来多大的影响。谢谢。
  • 这个问题很快就会得到解决。半年前我也有同样的想法,我仍然认为这个问题应该很快就会解决,但没有太多时间等待:)
【解决方案4】:

Swift 工具链仍然有点粗糙,您需要使用一些临时解决方法,直到 Apple 修复它(请参阅下面的更新

这里列出了您可以做的一些事情,以防止自己发疯。

不成熟的 Swift 编译器造成的缓慢

  • 使用 Injection for Xcode 更改您的开发工作流程。安装插件后,您将能够在您的模拟器\设备中注入代码更改而无需重新编译。您不需要硬编码\修改项目中的任何内容。我们最近开始在工作中使用它,它对我们产生了巨大的影响,即使它并不适用于每个用例(例如,您不能创建新功能,只能修改现有功能)。

  • 编译器不喜欢的一些特定代码结构,编译时间过长。最常见的问题是类型检查器会根据需要执行的类型检查次数以指数方式减慢编译时间(阅读更多here 获取实际示例,here 获取详细说明)。为了确定您是否遇到此问题,您可以关注此blog post,您将通过使用一些编译器附加标志来收集有关导致缓慢的函数的信息。或者,您可以使用此Xcode plugin 来确定构建缓慢的原因。

  • 在有意义的地方明智地使用动态框架。仅当您修改其中一个 Swift 文件时才会重新编译框架(动态框架仅适用于 iOS >= 7)。

  • 在同一文件中压缩代码。减少 Swift 文件的数量可以显着加快编译过程。您可以通过添加用户定义的自定义标志 SWIFT_WHOLE_MODULE_OPTIMIZATION 轻松实现它启用“整个模块优化”,并将其设置为 YES,同时将优化级别设置为无(禁用会使其慢)过时 你可以考虑使用这个gist,它是一个构建脚本,它将你所有的代码折叠在一个“merge.swift”文件中。 您需要为其创建一个新目标,但值得一试 试试看。

  • 仔细检查 here 列出的内容(还有一些其他原因,因为编译速度很慢)

  • 已过时 尝试blog post 中描述的方法,它涉及创建生成生成文件的构建脚本。它需要手动干预构建脚本(它包含 swift 文件列表)。

  • 过时 试试this破解的增量编译技术

更新:在 Swift 1.2 (Xcode 6.3) 上引入增量构建

Apple 终于推出了使用 Swift 1.2(随 Xcode 6.3 提供)的增量构建。它仍然不是完美的,但它是一个巨大的改进。

从现在开始,一个类只有在它被改变时才会被重新编译(或者当它所依赖的一个类被改变时)。 但是编译器仍然无法理解对类的更改是否针对其接口。因此,对类的任何更改都会导致该类及其所有依赖项的重新编译。

更新:仅在 Swift 2.1 (Xcode 7.1) 上引入公共接口更改时重新编译依赖类

从 Swift 2.1 (Xcode 7.1) 开始,依赖类仅在您更改类的公共接口时重新编译,而不是在每次更改时重新编译。这对大型项目来说尤其重要。

项目(错误)配置(与 Swift 无关)

  • 确保“仅构建活动架构”为“是”以进行调试。
  • 确保您没有添加需要太多时间的 pre\post 编译脚本。

【讨论】:

  • 感谢您的详细回答——很多优点,一定会尝试的。
  • 不客气。在答案中,我专注于如何加快编译速度。但是很明显,在您的情况下,您需要深入研究代码以找到导致编译器分段错误的问题。我认为段错误与项目的大小无关,您是否能够一致地重现它?如果是这样,您应该尝试隔离问题(因为您没有线索,您可以开始删除\评论类 - 我知道这有多难,但可以是一种方法)。 ps:你提到的框架有什么问题?我们非常明智地使用它们,我们没有问题。
  • 框架对我来说的主要问题,我还没有弄清楚,将Objective-C lib(例如FacebookSDK)添加到Swift Framework的正确方法是什么,框架内部没有桥接头,据我了解
  • 你需要在swift动态框架的伞头上直接导入每个Objective-c头。你可以在这里阅读更多关于框架的一般信息blog.cocoapods.org/Pod-Authors-Guide-to-CocoaPods-Frameworks 请注意,这不是关于框架的通用教程,但它包含很多很好的信息。当 cocoapods 将支持动态框架时,所有这些都应该通过框架的依赖关系自动处理,在 Podfile 中表示
  • 嘿 Alexey,看起来 Xcode 6.3 beta (swift 1.2) 可以完全解决这个问题,现在我们终于应该使用增量构建了,看起来他们解决了很多编译器错误,所以试试吧! .
【解决方案5】:

我发现分段错误和编译缓慢的主要原因之一是对大数组和字典进行硬编码,尤其是在将它们声明为全局常量并尝试从另一个 .swift 文件中访问它们的值时。当我将所有数据存储在 plist 中时,这些问题就消失了。

【讨论】:

    【解决方案6】:

    根据我的经验,避免创建大的 swift 文件,当我在新公司开始一个项目时,有一个 'UIViewController' 超过 2000 行,这个文件的小改动需要花费很多时间来构建,我从 class 做了 4 个extensions,

    【讨论】:

      猜你喜欢
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多