如何解决尝试评估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
:
-
在NSExpression或NSPredicate上使用受保护的变量名称(例如
size
)(应改为使用mySize
)。(在我的NSExpression示例中,成功完成了,因为我使用了变量名
myVar
,如果我试图将变量更改为size
,它会产生相同的SIGABRT
。 -
尝试将
myVar
与NSPredicate.withSubstitutionVariables(:)
一起使用(应改为使用$myVar
)。 -
尝试将
$myVar
与NSPredicate.evaluate(with:)
一起使用(应改为使用myVar
)。 -
尝试将
$myVar
与NSExpression.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 举报,一经查实,本站将立刻删除。