You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode 14运行Swift代码时出现编译器错误求助

Xcode 14 编译超时错误解决思路

问题描述

升级Xcode至14版本后,以下代码出现编译错误:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

报错指向let task = defaultSession.dataTask(with: url) { [self] (data, response, error) in这一行,但其他包含类似dataTask代码的函数运行正常,相关代码如下:

func LoadRecency2() {

    let url: URL = URL(string: "\(strGlobalPHPServer)listrecency.php?datedeb=\(strD)&datefin=\(strF)&rating=\(strR)")!
    print(url)

    let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)

    let task = defaultSession.dataTask(with: url) { [self] (data, response, error) in
        
        if error != nil {
            print("Failed to download Recency data")
        }
        else {
            print("Recency data downloaded")
            do {
                let decoder = JSONDecoder()
                do {
                    myJson = try decoder.decode([RecencyData].self, from: data!)
                }
                catch {
                    print(error)
                }
            }
            DispatchQueue.main.async { [self] in
                arrayRecencyPk.removeAll()
                arrayRecencyDate.removeAll()
                arrayRecencyAtrJour.removeAll()
                arrayRecencyAtrNuit.removeAll()
                arrayRecencyNav1.removeAll()
                arrayRecencyNav2.removeAll()
                arrayRecencyNav3.removeAll()
                arrayRecencyNav4.removeAll()
                arrayRecencyAJ1.removeAll()
                arrayRecencyAJ2.removeAll()
                arrayRecencyAJ3.removeAll()
                arrayRecencyAJ4.removeAll()
                arrayRecencyAN1.removeAll()
                arrayRecencyAN2.removeAll()
                arrayRecencyAN3.removeAll()
                arrayRecencyAN4.removeAll()
                arrayRecencyACrating.removeAll()
                arrayRecencyACtype.removeAll()
                arrayRecencyACimmat.removeAll()
                arrayRecencyACcolor.removeAll()
                arrayRecencyACsim.removeAll()

                if myJson.count > 0 {
                    for intX in 0...myJson.count - 1 {
                        arrayRecencyPk.append(myJson[intX].Pk)
                        var dateTmp: Date = dateFormatterPHPtime.date(from: myJson[intX].DateMission)!
                        let strDateTmp = dateFormatterPHP.string(from: dateTmp)
                        dateTmp = dateFormatterPHP.date(from: strDateTmp)!
                        arrayRecencyDate.append(dateTmp)
                        arrayRecencyAtrJour.append(myJson[intX].AtrJour)
                        arrayRecencyAtrNuit.append(myJson[intX].AtrNuit)
                        arrayRecencyNav1.append(myJson[intX].Nav1)
                        arrayRecencyNav2.append(myJson[intX].Nav2)
                        arrayRecencyNav3.append(myJson[intX].Nav3)
                        arrayRecencyNav4.append(myJson[intX].Nav4)
                        arrayRecencyACrating.append(myJson[intX].ACrating)
                        arrayRecencyACtype.append(myJson[intX].ACtype)
                        arrayRecencyACimmat.append(myJson[intX].ACimmat)
                        arrayRecencyACcolor.append(myJson[intX].ACcolor)
                        arrayRecencyACsim.append(myJson[intX].ACsim)

                        let intAJ = Int(myJson[intX].AtrJour)
                        let intAJ4 = Int(intAJ! / 262144)
                        let intAJ3 = Int((intAJ! - (intAJ4 * 262144)) / 4096)
                        let intAJ2 = Int((intAJ! - (intAJ4 * 262144) - (intAJ3 * 4096)) / 64)
                        let intAJ1 = Int(intAJ! - (intAJ4 * 262144) - (intAJ3 * 4096) - (intAJ2 * 64))

                        arrayRecencyAJ1.append(intAJ1)
                        arrayRecencyAJ2.append(intAJ2)
                        arrayRecencyAJ3.append(intAJ3)
                        arrayRecencyAJ4.append(intAJ4)

                        let intAN = Int(myJson[intX].AtrNuit)
                        let intAN4 = Int(intAN! / 262144)
                        let intAN3 = Int((intAN! - (intAN4 * 262144)) / 4096)
                        let intAN2 = Int((intAN! - (intAN4 * 262144) - (intAN3 * 4096)) / 64)
                        let intAN1 = Int(intAN! - (intAN4 * 262144) - (intAN3 * 4096) - (intAN2 * 64))

                        arrayRecencyAN1.append(intAN1)
                        arrayRecencyAN2.append(intAN2)
                        arrayRecencyAN3.append(intAN3)
                        arrayRecencyAN4.append(intAN4)
                    }
                }
                lblDownloadStatus.text = "STEP 2/4 : Downloading Recency data..."
                LoadRecencyDev()
            }
        }
    }
    task.resume()
}

解决思路与修改方案

1. 拆分闭包内的复杂逻辑

编译器报错的核心原因是dataTask的闭包内嵌套了JSON解析、大量数组操作、多层循环计算,代码量过大导致类型检查超时。将闭包内的逻辑拆分为独立函数,降低单个代码块的复杂度:

拆分出数据解析函数

private func processRecencyData(_ data: Data) {
    do {
        let decoder = JSONDecoder()
        myJson = try decoder.decode([RecencyData].self, from: data)
        // 解析完成后切换到主线程更新UI和数组
        DispatchQueue.main.async { [self] in
            updateRecencyDisplayArrays()
            lblDownloadStatus.text = "STEP 2/4 : Downloading Recency data..."
            LoadRecencyDev()
        }
    } catch {
        print("JSON解析失败: \(error)")
    }
}

拆分出数组更新函数

private func updateRecencyDisplayArrays() {
    // 清空所有数组
    arrayRecencyPk.removeAll()
    arrayRecencyDate.removeAll()
    arrayRecencyAtrJour.removeAll()
    arrayRecencyAtrNuit.removeAll()
    arrayRecencyNav1.removeAll()
    arrayRecencyNav2.removeAll()
    arrayRecencyNav3.removeAll()
    arrayRecencyNav4.removeAll()
    arrayRecencyAJ1.removeAll()
    arrayRecencyAJ2.removeAll()
    arrayRecencyAJ3.removeAll()
    arrayRecencyAJ4.removeAll()
    arrayRecencyAN1.removeAll()
    arrayRecencyAN2.removeAll()
    arrayRecencyAN3.removeAll()
    arrayRecencyAN4.removeAll()
    arrayRecencyACrating.removeAll()
    arrayRecencyACtype.removeAll()
    arrayRecencyACimmat.removeAll()
    arrayRecencyACcolor.removeAll()
    arrayRecencyACsim.removeAll()

    guard !myJson.isEmpty else { return }
    
    // 遍历数据填充数组,用for-in替代下标遍历,简化逻辑
    for item in myJson {
        arrayRecencyPk.append(item.Pk)
        
        // 处理日期转换,用可选绑定替代强制解包
        guard let dateTmp = dateFormatterPHPtime.date(from: item.DateMission),
              let formattedDateStr = dateFormatterPHP.string(from: dateTmp).flatMap(dateFormatterPHP.date) else {
            continue
        }
        arrayRecencyDate.append(formattedDateStr)
        
        arrayRecencyAtrJour.append(item.AtrJour)
        arrayRecencyAtrNuit.append(item.AtrNuit)
        arrayRecencyNav1.append(item.Nav1)
        arrayRecencyNav2.append(item.Nav2)
        arrayRecencyNav3.append(item.Nav3)
        arrayRecencyNav4.append(item.Nav4)
        arrayRecencyACrating.append(item.ACrating)
        arrayRecencyACtype.append(item.ACtype)
        arrayRecencyACimmat.append(item.ACimmat)
        arrayRecencyACcolor.append(item.ACcolor)
        arrayRecencyACsim.append(item.ACsim)

        // 简化AtrJour的计算逻辑,减少重复计算
        if let intAJ = Int(item.AtrJour) {
            let intAJ4 = intAJ / 262144
            let remainingAfterAJ4 = intAJ - intAJ4 * 262144
            let intAJ3 = remainingAfterAJ4 / 4096
            let remainingAfterAJ3 = remainingAfterAJ4 - intAJ3 * 4096
            let intAJ2 = remainingAfterAJ3 / 64
            let intAJ1 = remainingAfterAJ3 - intAJ2 * 64
            
            arrayRecencyAJ1.append(intAJ1)
            arrayRecencyAJ2.append(intAJ2)
            arrayRecencyAJ3.append(intAJ3)
            arrayRecencyAJ4.append(intAJ4)
        }

        // 简化AtrNuit的计算逻辑
        if let intAN = Int(item.AtrNuit) {
            let intAN4 = intAN / 262144
            let remainingAfterAN4 = intAN - intAN4 * 262144
            let intAN3 = remainingAfterAN4 / 4096
            let remainingAfterAN3 = remainingAfterAN4 - intAN3 * 4096
            let intAN2 = remainingAfterAN3 / 64
            let intAN1 = remainingAfterAN3 - intAN2 * 64
            
            arrayRecencyAN1.append(intAN1)
            arrayRecencyAN2.append(intAN2)
            arrayRecencyAN3.append(intAN3)
            arrayRecencyAN4.append(intAN4)
        }
    }
}

2. 简化主函数,显式指定类型

修改LoadRecency2函数,显式指定闭包参数类型,用可选绑定替代强制解包,减少编译器推断压力:

func LoadRecency2() {
    // 用guard处理URL创建失败的情况,替代强制解包
    guard let url = URL(string: "\(strGlobalPHPServer)listrecency.php?datedeb=\(strD)&datefin=\(strF)&rating=\(strR)") else {
        print("无效的请求URL")
        return
    }
    print(url)

    let defaultSession = URLSession(configuration: .default)

    // 显式指定闭包参数类型,避免编译器耗时推断
    let task = defaultSession.dataTask(with: url) { [self] (data: Data?, response: URLResponse?, error: Error?) in
        if let error = error {
            print("Recency数据下载失败: \(error.localizedDescription)")
            return
        }
        
        guard let data = data else {
            print("未接收到数据")
            return
        }
        
        print("Recency数据下载完成")
        // 调用拆分后的解析函数
        processRecencyData(data)
    }
    task.resume()
}

3. 其他优化点

  • 移除不必要的嵌套:原代码中do-catch嵌套可以合并,减少层级
  • 替换强制解包:用guard或if let处理可选值,既避免崩溃,也降低编译器类型检查的复杂度
  • 简化重复计算:将重复的数值计算逻辑拆分,减少冗余代码,让编译器更容易分析

内容的提问来源于stack exchange,提问作者hgiraud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:00:30