Xcode 8.0 Swift 3.0 索引和构建速度慢

Xcode 8.0 Swift 3.0 slow indexing and building

我已经安装了Xcode 8.0 并将Swift 2.2 转换为3.0(这个过程也花了很多时间,我只是把我的Mac 运行夜晚)。我没有一个大项目(大约 20 个文件)。我也在使用 Pods。以前 Xcode 版本(< 8.0)的索引工作很快,但现在,升级后,进度条卡在一个位置(我已经等了一个小时)。

我尝试过但对我没有帮助的事情:

当开发人员不得不花费数小时来解决这些荒谬的问题时,发布这样的软件真的很不酷。这是非常令人失望的。 有什么解决办法吗?

我通过注释所有文件然后一一删除注释解决了这个问题。我发现问题仍然在数组声明中,如 here.

所述

我有这样的代码,但项目没有编制索引:

class {
    var first: String!
    var second: String!
    var third: String!
    var fourth: String!
    var fifth: String!

    func abc() -> [String] {
        var array = [first, second, third, fourth, fifth]
    }
}

我已将其更改为这个并且索引开始工作:

class {
    var first: String!
    var second: String!
    var third: String!
    var fourth: String!
    var fifth: String!

    func abc() -> [String] {
        var array = [first]

        array.append(second)
        array.append(third)
        array.append(fourth)
        array.append(fifth)
    }
}

转到项目设置,然后编辑器 > 添加构建设置 > 添加用户定义的设置,然后添加以下内容:

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

对于一个 40KLOC swift 项目,添加此标志后,我们的干净构建编译时间奇迹般地从 7 分钟减少到 65 秒。也可以确认2位朋友在企业项目上看到了类似的改进。

我只能假设这是 Xcode 8.0

中的某种错误

自从升级到 Swift 3/XCode 8 后,我遇到了同样的问题,这似乎是由大数组文字引起的。

我能够通过向分配给数组文字的变量添加类型注释来解决这个问题,例如

let array: Array<String> = ["1", "2", "3", "4", "5", "6", "7", "8"]

而不是

let array = ["1", "2", "3", "4", "5", "6", "7", "8"]

我遇到了类似的问题并按照本指南进行了调试:http://irace.me/swift-profiling 我的问题是我在某些字符串中有 nil 合并运算符,例如:

let name = "\(someString ?? "")"

这四种方法导致构建时间增加了 2 分钟。

我尝试了上述解决方案,但问题仍然存在。调试工作也很奇怪。经过几天的研究,我找到了以下解决方案。

Select 主要目标 > 构建设置。配置如下图

添加设置后,

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

我们的项目 clean-build 编译时间从 1200 秒到 180 秒,用于 650 个 swift 文件。但这会导致增加编译失败。每个改动需要180s编译,增加编译只需要60s

对于那些想要找到编译器所在位置的人 "caught"

添加到 Other Swift Flags -Xfrontend -warn-long-function-bodies=50

查看完整答案here

这是一个 Xcode 错误 (Xcode 8.2.1),当您有一个大的字典文字或嵌套的字典文字时,它就会发生。你必须把你的字典分解成更小的部分,然后用 append 方法添加它们,直到 Apple 修复这个错误。

我遇到了同样的问题并通过逐行仔细检查我的代码解决了它,结果 Swift 3 更喜欢字符串插值而不是使用 + 符号,即

let url = "http://yahoo.com" + "someWebPage" + "whereItsInteresting" 

如果您一直在使用上述代码风格,请将其替换为;

let url = "http://yahoo.com\(someWebPage)\(whereItsInteresting)"

并且您的构建时间将立即恢复正常。

当 "Indexing" 卡住时,这对我在 Xcode 8.2.1 和 Swift 3 中有效:

我总是打开两个项目,一个虚拟项目和我正在处理的项目。我还连接了一个 iPad Air 设备,我 运行 我的项目就在上面。当我的项目卡在 "Indexing" 上时,我切换到我的虚拟项目和 运行 我连接的 iPad Air 设备上的项目。然后我停止项目 然后切换回我正在处理的项目,"Indexing" 神奇地完成了。如果您没有连接物理设备,这也应该只适用于模拟器。

我遇到了同样的索引问题,但只有当我在设备上 running/debugging 然后切换到左上角工具栏上的另一台设备时才会发生(目标 > iPhone)。

None 以上解决方案对我有用。

我的解决方案: 我删除了我的本地 git 工作副本并从我的 'origin'.

克隆了一个新的

(xcuserdata/shared/session 等文件夹中有一些 'magic' 文件可能导致了这个问题?)

为我解决这个问题的方法是使用键来设置字典值

let dict: [string:any]()
dict["key"] = "value"
dict["key1"] = "value"
dict["key2"] = "value"
return dict

如果您的字典很长,它可能会或可能不会导致编译循环,从而导致构建时间过长。任何超过 8 个键的东西都应该设置。

并不是说我认为这与 OP 的问题有关,但 XCode 8 最近对我来说变慢了。我最终发现这是我的错误(我记得是无意中这样做的)——我添加了 XCode.app 作为框架参考。这基本上使 XCode 搜索并索引整个 XCode.app 文件夹。一旦我看到错误并删除框架,它又恢复正常了:)

我有一个函数需要一分钟的时间来编译,经过一些调查,我发现罪魁祸首正在检查从存储日期开始是否已经过去了足够的时间:

let myStoredDate: Double = // Double representing a time in the past

// if at least one week (60 * 60 * 24 * 7 seconds) has passed since myStoredDate
if Date().timeIntervalSince1970 - myStoredDate > (60 * 60 * 24 * 7){
    // do stuff
}

这段代码需要 10 多秒的时间来编译——再加上这段代码用不同的数字重复多次,导致编译时间过长。我能够通过预先计算间隔

来解决这个问题
let myStoredDate = // Double representing a time in the past

//it is important to explicitly specify that the variable is a Double
let interval: Double = 60 * 60 * 24 * 7

if Date().timeIntervalSince1970 - myStoredDate > interval{
    // do stuff
}

在我检查了大约 10 次之后,编译时间从一分钟多缩短到几毫秒。

此问题极有可能在其他地方结合使用类型推断和数学时也会发生,因此请确保您的代码中的其他地方不会发生此类情况。

我的问题是字典。我有很多大词典。

let values = ["address":addressTextField.text,"city":cityTextField.text,"zipCode":zipCodeTextField.text,"state":stateTextField.text,"pet":answerLabel.text,"rentStart":rentStartTextField.text,"rentEnd":rentEndTextField.text,"rent":rentTextField.text,"phone":phoneTextField.text,"email":emailTextField.text,"status":leaseStatusTextField.text,"bedrooms":bedroomTextField.text,"parking":parkingLabel.text,"furnish":furnishLabel.text,"utilities":utilitiesTextField.text,"laundry":laundryTextField.text,"paymentCycle":paymentCycleTextField.text,"note":noteTextView.text]

我将其分解为:

        var values = ["address":addressTextField.text]
        values["city"] = cityTextField.text
        values["zipCode"] = zipCodeTextField.text
        values["state"] = stateTextField.text
        values["pet"] = answerLabel.text
        values["rentStart"] = rentStartTextField.text
        values["rentEnd"] = rentEndTextField.text
        values["rent"] = rentTextField.text
        values["phone"] = phoneTextField.text
        values["email"] = emailTextField.text
        values["status"] = leaseStatusTextField.text
        values["bedrooms"] = bedroomTextField.text
        values["parking"] = parkingLabel.text
        values["furnish"] = furnishLabel.text
        values["utilities"] = utilitiesTextField.text
        values["laundry"] = laundryTextField.text
        values["paymentCycle"] = paymentCycleTextField.text
        values["note"] = noteTextView.text
        values["owner"] = userID

备份你的项目备份后删除最后更新的项目然后重启Xcode简单:-)

我遇到过类似的问题并开发了自己的实用程序 Rugby。 在当前版本中,Rugby 可以缓存所有远程 pods 依赖项并从 Pods 项目中删除它们的目标。\

在幕后,它正在使用一些优化。例如,像 SWIFT_COMPILATION_MODE=wholemodule.