微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试评估NSExpression或NSPredicate时使用SIGABRT

如何解决尝试评估NSExpression或NSPredicate时使用SIGABRT

我正在尝试结合NSExpression + NSPredicate来创建一个简单的功能用户可以在其中键入类似size + 1 > 3内容,并将对表达式求值。

首先,为了确保我可以让NSExpression使用变量,我尝试了以下操作:

NSExpression(format: "2 + 1")
  .expressionValue(with: nil,context: nil)
// == 3

NSExpression(format: "myInt + 1")
  .expressionValue(with: ["myInt": 2],context: nil)
// == 3

接下来,为确保我可以评估nspredicate,我尝试了以下操作:

nspredicate(format: "2 + 1 == 3")
  .evaluate(with: nil)
// == true

现在,当我尝试将两者结合时,无论尝试哪种结合,我都会得到error: Execution was interrupted,reason: signal SIGABRT.

nspredicate(format: "size + 1 == 3")
  .evaluate(with: ["size": 2])
// error: Execution was interrupted,reason: signal SIGABRT.

nspredicate(format: "$size + 1 == 3")
  .evaluate(with: ["size": 2])
// error: Execution was interrupted,reason: signal SIGABRT.

nspredicate(format: "size + 1 == 3")
  .withSubstitutionVariables(["size": 2])
  .evaluate(with: nil)
// error: Execution was interrupted,reason: signal SIGABRT.

nspredicate(format: "$size + 1 == 3")
  .withSubstitutionVariables(["size": 2])
  .evaluate(with: nil)
// error: Execution was interrupted,reason: signal SIGABRT.

我知道大多数nspredicate都是用于过滤列表的,这让我想知道上述的用例是否还可以工作。

是否可以在一次评估的nspredicate中使用变量?

解决方法

上面的代码中有几件事可能导致SIGABRT

  1. 在NSExpression或NSPredicate上使用受保护的变量名称(例如size)(应改为使用mySize)。

    (在我的NSExpression示例中,成功完成了,因为我使用了变量名myVar,如果我试图将变量更改为size,它会产生相同的SIGABRT

  2. 尝试将myVarNSPredicate.withSubstitutionVariables(:)一起使用(应改为使用$myVar)。

  3. 尝试将$myVarNSPredicate.evaluate(with:)一起使用(应改为使用myVar)。

  4. 尝试将$myVarNSExpression.evaluate(with:context:)一起使用(应改为使用myVar)。

这两种方法都可以使用:

NSPredicate(format: "mySize + 1 == 3")
  .evaluate(with: ["mySize": 2])
// == true

NSPredicate(format: "$mySize + 1 == 3")
  .withSubstitutionVariables(["mySize": 2])
  .evaluate(with: nil)
// == true

您甚至可以在两个变量中定义相同的变量:

NSPredicate(format: "mySize == $mySize")
  .withSubstitutionVariables(["mySize": 2])
  .evaluate(with: ["mySize": 2])
// == true

但是,您可能只想坚持一个或另一个。

更新:就避免使用保留关键字而言,您可以将提供的词典与Martin链接到的以下列表进行比较:

/// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html
let reservedKeywords = ["AND","OR","IN","NOT","ALL","ANY","SOME","NONE","LIKE","CASEINSENSITIVE","CI","MATCHES","CONTAINS","BEGINSWITH","ENDSWITH","BETWEEN","NULL","NIL","SELF","TRUE","YES","FALSE","NO","FIRST","LAST","SIZE","ANYKEY","SUBQUERY","FETCH","CAST","TRUEPREDICATE","FALSEPREDICATE","UTI-CONFORMS-TO","UTI-EQUALS"]

您需要进行不区分大小写的比较。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。