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

Xcode 16编译报错:Predicate表达式过于复杂无法类型检查

Xcode 16编译Predicate宏时出现类型检查超时问题

在Xcode 16中编译代码时,遇到错误提示:"编译器无法在合理时间内对此表达式进行类型检查;尝试将表达式拆分为不同的子表达式",错误出现在#Predicate宏的展开位置。相同代码在Xcode 15中可正常编译运行,移除6个用||分隔的条件中的任意2个后,编译就能正常通过。

原代码

class FeaturesPredicate {
    class func predicate(_ enabledFeaturesName: String) -> Predicate<Caliber> {
        #Predicate {
            caliber in
            caliber.caliberData.featuresABCD.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresA.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresB.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresC.contains {
                feature in
                enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresD.contains {
               feature in
               enabledFeaturesName == feature.name
            } || caliber.caliberData.featuresN.contains {
                feature in
                enabledFeaturesName == feature.name
            }
        }
    }
}

宏展开后的代码

Foundation.Predicate({
    caliber in
    PredicateExpressions.build_Disjunction(
        lhs: PredicateExpressions.build_Disjunction(
            lhs: PredicateExpressions.build_Disjunction(
                lhs: PredicateExpressions.build_Disjunction(
                    lhs: PredicateExpressions.build_Disjunction(
                        lhs: PredicateExpressions.build_contains(
                            PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_Arg(caliber),
                                    keyPath: \.caliberData
                                ),
                                keyPath: \.featuresABCD
                            )
                        ) {
                            feature in
                            PredicateExpressions.build_Equal(
                                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                                rhs: PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_Arg(feature),
                                    keyPath: \.name
                                )
                            )
                        },
                        rhs: PredicateExpressions.build_contains(
                            PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_Arg(caliber),
                                    keyPath: \.caliberData
                                ),
                                keyPath: \.featuresA
                            )
                        ) {
                            feature in
                            PredicateExpressions.build_Equal(
                                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                                rhs: PredicateExpressions.build_KeyPath(
                                    root: PredicateExpressions.build_Arg(feature),
                                    keyPath: \.name
                                )
                            )
                        }
                    ),
                    rhs: PredicateExpressions.build_contains(
                        PredicateExpressions.build_KeyPath(
                            root: PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_Arg(caliber),
                                keyPath: \.caliberData
                            ),
                            keyPath: \.featuresB
                        )
                    ) {
                        feature in
                        PredicateExpressions.build_Equal(
                            lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                            rhs: PredicateExpressions.build_KeyPath(
                                root: PredicateExpressions.build_Arg(feature),
                                keyPath: \.name
                            )
                        )
                    }
                ),
                rhs: PredicateExpressions.build_contains(
                    PredicateExpressions.build_KeyPath(
                        root: PredicateExpressions.build_KeyPath(
                            root: PredicateExpressions.build_Arg(caliber),
                            keyPath: \.caliberData
                        ),
                        keyPath: \.featuresC
                    )
                ) {
                    feature in
                    PredicateExpressions.build_Equal(
                        lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                        rhs: PredicateExpressions.build_KeyPath(
                            root: PredicateExpressions.build_Arg(feature),
                            keyPath: \.name
                        )
                    )
                }
            ),
            rhs: PredicateExpressions.build_contains(
                PredicateExpressions.build_KeyPath(
                    root: PredicateExpressions.build_KeyPath(
                        root: PredicateExpressions.build_Arg(caliber),
                        keyPath: \.caliberData
                    ),
                    keyPath: \.featuresD
                )
            ) {
               feature in
                PredicateExpressions.build_Equal(
                    lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                    rhs: PredicateExpressions.build_KeyPath(
                        root: PredicateExpressions.build_Arg(feature),
                        keyPath: \.name
                    )
                )
            }
        ),
        rhs: PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(
                root: PredicateExpressions.build_KeyPath(
                    root: PredicateExpressions.build_Arg(caliber),
                    keyPath: \.caliberData
                ),
                keyPath: \.featuresN
            )
        ) {
                feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(
                    root: PredicateExpressions.build_Arg(feature),
                    keyPath: \.name
                )
            )
        }
    )
})

解决方案

方案1:拆分表达式为独立子Predicate

将每个contains条件拆成单独的Predicate,再通过逻辑或组合,降低编译器类型检查的复杂度:

class FeaturesPredicate {
    class func predicate(_ enabledFeaturesName: String) -> Predicate<Caliber> {
        let featureABCD = #Predicate<Caliber> { $0.caliberData.featuresABCD.contains { $0.name == enabledFeaturesName } }
        let featureA = #Predicate<Caliber> { $0.caliberData.featuresA.contains { $0.name == enabledFeaturesName } }
        let featureB = #Predicate<Caliber> { $0.caliberData.featuresB.contains { $0.name == enabledFeaturesName } }
        let featureC = #Predicate<Caliber> { $0.caliberData.featuresC.contains { $0.name == enabledFeaturesName } }
        let featureD = #Predicate<Caliber> { $0.caliberData.featuresD.contains { $0.name == enabledFeaturesName } }
        let featureN = #Predicate<Caliber> { $0.caliberData.featuresN.contains { $0.name == enabledFeaturesName } }
        
        return featureABCD || featureA || featureB || featureC || featureD || featureN
    }
}

方案2:重构数据结构合并特征数组

如果业务允许,将多个特征数组合并为一个统一数组,大幅简化Predicate逻辑:

// 先给CaliberData添加合并后的特征数组
extension CaliberData {
    var allFeatures: [Feature] {
        featuresABCD + featuresA + featuresB + featuresC + featuresD + featuresN
    }
}

// 简化后的Predicate实现
class FeaturesPredicate {
    class func predicate(_ enabledFeaturesName: String) -> Predicate<Caliber> {
        #Predicate {
            $0.caliberData.allFeatures.contains { $0.name == enabledFeaturesName }
        }
    }
}

方案3:手动构建Predicate表达式

直接使用PredicateExpressionsAPI手动构建逻辑,避免宏展开时的深层嵌套:

class FeaturesPredicate {
    class func predicate(_ enabledFeaturesName: String) -> Predicate<Caliber> {
        let caliberArg = PredicateExpressions.build_Arg(Caliber.self)
        let caliberDataKeyPath = PredicateExpressions.build_KeyPath(root: caliberArg, keyPath: \.caliberData)
        
        // 逐个构建每个特征数组的检查表达式
        let abcdCheck = PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(root: caliberDataKeyPath, keyPath: \.featuresABCD)
        ) { feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(root: PredicateExpressions.build_Arg(feature), keyPath: \.name)
            )
        }
        
        let aCheck = PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(root: caliberDataKeyPath, keyPath: \.featuresA)
        ) { feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(root: PredicateExpressions.build_Arg(feature), keyPath: \.name)
            )
        }
        
        let bCheck = PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(root: caliberDataKeyPath, keyPath: \.featuresB)
        ) { feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(root: PredicateExpressions.build_Arg(feature), keyPath: \.name)
            )
        }
        
        let cCheck = PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(root: caliberDataKeyPath, keyPath: \.featuresC)
        ) { feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(root: PredicateExpressions.build_Arg(feature), keyPath: \.name)
            )
        }
        
        let dCheck = PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(root: caliberDataKeyPath, keyPath: \.featuresD)
        ) { feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(root: PredicateExpressions.build_Arg(feature), keyPath: \.name)
            )
        }
        
        let nCheck = PredicateExpressions.build_contains(
            PredicateExpressions.build_KeyPath(root: caliberDataKeyPath, keyPath: \.featuresN)
        ) { feature in
            PredicateExpressions.build_Equal(
                lhs: PredicateExpressions.build_Arg(enabledFeaturesName),
                rhs: PredicateExpressions.build_KeyPath(root: PredicateExpressions.build_Arg(feature), keyPath: \.name)
            )
        }
        
        // 逐步组合逻辑或表达式
        let combined = PredicateExpressions.build_Disjunction(lhs: abcdCheck, rhs: aCheck)
        let combined2 = PredicateExpressions.build_Disjunction(lhs: combined, rhs: bCheck)
        let combined3 = PredicateExpressions.build_Disjunction(lhs: combined2, rhs: cCheck)
        let combined4 = PredicateExpressions.build_Disjunction(lhs: combined3, rhs: dCheck)
        let final = PredicateExpressions.build_Disjunction(lhs: combined4, rhs: nCheck)
        
        return Predicate(final)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:25:56