我可以通过格式字符串将运算符传递给NSPredicate吗?

时间:2013-05-17 20:14:23

标签: ios core-data nspredicate predicate

我正在尝试创建以下谓词

[NSPredicate predicateWithFormat:@"name != %@ AND date %@ %@", varName, operator, varDate]

其中varNamevarDate分别是NSString和NSDate对象。 operator变量的声明如下:

NSString *operator = (direction == kPageDirectionForward) ? @">" : @"<";

基本上我想在创建谓词时保存几行。我知道我可以根据direction的值创建不同的谓词,但这个用例让我思考。

现在这个当前的方法崩溃了,所以我认为不可能。我想知道是否有其他人有运气。

4 个答案:

答案 0 :(得分:2)

您可以结合使用NSComparisonPredicateNSCompoundPredicate

来实现这一目标
// First part: name != <varName>
NSPredicate *p1 = [NSPredicate predicateWithFormat:@"name != %@", varName];

// Second part: date <op> <varDate>
NSExpression *lexp = [NSExpression expressionForKeyPath:@"date"];
NSExpression *rexp = [NSExpression expressionForConstantValue:varDate];
NSPredicateOperatorType op = (direction == kPageDirectionForward) ? NSGreaterThanPredicateOperatorType : NSLessThanOrEqualToPredicateOperatorType;
NSPredicate *p2 = [NSComparisonPredicate predicateWithLeftExpression:lexp
                                                     rightExpression:rexp
                                                            modifier:0
                                                                type:op
                                                             options:0];
// predicate = <p1> AND <p2>
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[p1, p2]];

答案 1 :(得分:2)

我意识到这与op关于使用不同谓词字符串的陈述没有根本的不同,但你可以动态地构建谓词字符串:

NSString *operator = (direction == kPageDirectionForward) ? @">" : @"<";

NSMutableString * predicateString = [NSMutableString stringWithString: @"name != %@ AND date "];
[predicateString appendString: operator];
[predicateString appendString: @" %@"];
[NSPredicate predicateWithFormat: predicateString, varName, varDate];
// should return valid predicate: @"name != %@ AND date < %@"

作为一个稍微离奇的例子,只要您查询nsobjects,这应该有效:

NSString * predicateString = [NSString stringWithFormat: @"name != %@ AND date %@ %@", @"%@", operator, @"%@"];
[NSPredicate predicateWithFormat: predicateString, varName, varDate];

答案 2 :(得分:2)

真的有更有效的方法:

{{1}}

答案 3 :(得分:1)

您不能这样做,因为格式字符串与提供的参数不同,因为在处理格式字符串以生成有效且可解析的谓词字符串时,将引用提供的参数。