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
相关产品推荐
相关产品推荐

