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

Swift中GKRuleSystem与NSPredicate使用结果异常,求正确用法

Swift中GKRuleSystem规则判断问题修正

问题现象

用Swift实现的GKRuleSystem规则判断逻辑,无论distanceToPlayer取何值,hunt事实的判断结果始终为True,不符合预期;而对应的Objective-C版本逻辑正常——当玩家距离近时会撤回hunt事实,结果为False。

核心问题

对比两段代码可以发现,Swift版本中玩家近距离规则的类型错误:

  • Objective-C代码中,近距离规则使用retractingFact:@"hunt"(撤回事实)
  • Swift代码中,错误地使用了assertingFact: assertingFactKey(断言事实)

这导致无论玩家远近,两条规则都在断言hunt事实,最终grade始终大于0,结果永远为True。

修正后的Swift代码

let assertingFactKey = "hunt"
let ruleSystem = GKRuleSystem()

// 玩家远距离时,断言hunt事实
let playerFar = NSPredicate(format: "$distanceToPlayer.floatValue >= 10.0")
ruleSystem.add(GKRule(predicate: playerFar, assertingFact: assertingFactKey, grade: 1.0))

// 玩家近距离时,撤回hunt事实
let playerNear = NSPredicate(format: "$distanceToPlayer.floatValue < 10.0")
ruleSystem.add(GKRule(predicate: playerNear, retractingFact: assertingFactKey, grade: 1.0))

for i in 1...30 {
    ruleSystem.state["distanceToPlayer"] = NSNumber(value: i) // 存入NSNumber,匹配predicate的floatValue调用
    ruleSystem.reset()
    ruleSystem.evaluate()
    let result = ruleSystem.grade(forFact: assertingFactKey) > 0.0
    print(result ? "**True : \(i)" : "**False")
}

额外说明

  1. assertingFactKey无需转成NSString,Swift原生String可以直接与GKRuleSystem兼容。
  2. 向ruleSystem.state存入NSNumber而非直接存Int,能更稳妥地匹配谓词中的.floatValue调用,避免类型转换问题。
  3. 修正后运行结果与Objective-C版本一致:当i < 10时输出**False,i >=10时输出**True : [i]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:50:19