当前位置: 首页 > 知识库问答 >
问题:

Xcode 11重新编译太多了

巴宏恺
2023-03-14

Xcode 11 正在重新编译(几乎?)我的整个项目,即使我只是更改一个局部私有变量,或者在局部作用域中更改一个常量的值,有时甚至在局部私有函数作用域中。我有时可以通过预期的快速构建获得2或3个更改,但很快它决定再次重新编译所有内容(这需要太长时间)。

知道可能发生了什么吗?Xcode无法确定发生了什么变化,为什么它会重新编译这么多其他东西(甚至其他模块)。

任何建议都非常感谢,谢谢!

共有2个答案

张俊茂
2023-03-14

这里没有金科玉律,但是有很多东西需要检查:

如果您使用的是类型推断繁重的框架(如 RxSwift),则添加显式类型注释可以加快构建时间。

如果项目非常大,您可以考虑将源文件的逻辑组重构到框架中,但这可能比您希望的要大得多。

如果您提供关于项目的更多细节,可能会有所帮助:您是否静态链接了任何库?它是框架还是应用程序目标?你用的是多大和多快的版本?您是否有一些定制的构建阶段,例如有时可以跳过的过梁或代码生成?

赫连泰宁
2023-03-14

我们遇到了同样的问题,我们解决了它。两次。

增量生成(相同的生成计算机):

前:~10m后:~35s

让我们先从我们的经验开始。我们有一个庞大的Swift/Obj-C项目,这是主要的问题:构建时间很慢,你必须创建一个新项目来实现一个新功能(字面意思)。永远不工作的语法高亮加分。

要真正解决这个问题,您必须真正了解构建系统的工作原理。例如,让我们试试这个代码片段:

import FacebookSDK
import RxSwift
import PinLayout

想象一下,您在文件中使用了所有这些导入。而且这个文件依赖于另一个文件,它依赖于另一个库,而另一个库又使用另一个库等。

所以为了编译你的文件,Xcode必须编译你提到的每一个库和它依赖的每一个文件,所以如果你改变了一个“核心”文件,Xcode必须重建整个项目。

Xcode 构建是多线程的,但它由许多单线程树组成。

因此,在每个增量构建的第一步,Xcode都是决定哪些文件必须重新编译,并构建一个AST树。如果你改变了一个在其他文件上表现为“可靠”的文件,那么所有其他表现为“依赖”的文件都必须重新编译。

因此,第一个建议是降低耦合。您的项目部件必须彼此独立。

如果您使用的是Obj-C/Swift网桥,那么这些树存在问题,Xcode必须经历比平时更多的阶段:

完美世界:

  1. 生成奥布吉-C 代码
  2. 构建快速代码

奥布吉-C/斯威夫特桥:

  1. [可重复步骤] 编译 Obj-C 代码所需的快速代码
  2. [可重复步骤] 编译 Swift 代码所需的 Obj-C 代码
  3. 重复 1

因此,如果您从步骤1或2中更改某些内容,则基本上会遇到麻烦。最好的解决方案是最小化 Obj-C/斯威夫特桥(并将其从项目中删除)。

如果您没有 Obj-C/Swift 桥,那真是太棒了,您可以继续下一步:

是时候转向SwiftPM了(或者至少更好地配置您的Cocoapods)。

事实是,大多数带有默认Cocoapods配置的框架都附带了许多您不需要的东西。

要对此进行测试,请创建一个只有一个依赖项的空项目,例如PinLayout,并尝试使用Cocoapods(默认配置)和SwiftPM编写此代码。

import PinLayout

final class TestViewController: UIViewController {

}

Spoiler:Cocoapods将编译此代码,因为Cocoapod将导入PinLayout的每个import(包括UIKit),而SwiftPM将不会,因为SwiftAM自动导入框架。

你还记得Xcode build是多线程的吗?

嗯,你可以滥用它,如果你能够将你的项目拆分成许多独立的部分,并将它们作为独立的框架导入到你的项目中。它确实降低了耦合,这实际上是我们使用的第一个解决方案,但实际上并不是很有效,因为我们只能将增量构建时间减少到~45m这与第一种方法相比是微不足道的。

 类似资料:
  • 我正在尝试为Minecraft制作自定义启动器。我只想让它从我自己的服务器下载主jar文件,仅此而已。我反编译了一个文件(Launcher.java)并将下载url从“https://s3.amazonaws.com/Minecraft.Download/”更改为我自己的。问题是,当我尝试使用javac-classpath重新编译它时launcher.jarlauncher.java它会抛出5个错

  • 我使用maven命令来清理、构建整个项目、创建war并部署到服务器。我不能使用Intellij来做这件事,因为我只有社区版。它在与intellij相同的目录中构建项目。 为了加快速度,我编写了一个脚本,可以在本地“target”目录中找到比服务器中更新的已编译文件,并进行复制。虽然一切正常,但问题是Intellij并没有将使用maven编译的类视为应该跳过并重新构建整个项目的类。 目前它的工作原理

  • 变量res的值应等于3。但是当我打开优化时,编译器错误地重新排列了指令,并且res包含一些垃圾。一些可能的重新排序示例: 这是编译器中的错误吗?还是不允许像这样访问结构数据成员? 编辑: 我刚刚意识到之前的代码实际上有效,抱歉。但这不起作用: 当编译时不知道变量i时,编译器会错误地重新排序指令。

  • 我测试了标准的hello。java和你好。运行在Ubuntu12.04服务器上的gwan服务器附带的c。G-WAN 4.3.1 64位(2013年3月1日17:36:39) 一旦我和关一起 sudo./gwan-d 我还注意到在没有daemon选项的情况下也有同样的行为。 然后浏览到192.168.0.2:8080 /?hello.c我得到预期的输出“你好,ANSI C!我更改了hello.c中的

  • 有时你可能想添加必要的驱动、补丁、Kali Linux内核里没有的功能.如下的教程描述如何根据你的需要快速地修改和编译Kali Linux内核.请注意目前默认的Kali Linux内核已经打过了大量的无线注入补丁. 安装编译所需的依赖 开始安装编译内核所需的所有依赖. apt-get install kernel-package ncurses-dev fakeroot bzip2 下载Kali

  • 问题内容: 我确实知道重载和重载之间的语法差异。而且我也知道,重载是运行时多态,重载是编译时多态。但是我的问题是:“重载真的是编译时的多态性吗?方法调用真的在编译时解决了吗?”。为了阐明我的观点,让我们考虑一个示例类。 由于所有方法都是公开的,因此可以全部重写(包括重载的方法),对吗?例如, 现在,考虑以下代码片段: 该方法返回一个随机对象。它可以返回的对象,或者它的任何子类,例如或或任何其他一个