问题
The following code raises a question
NSPredicate * myPred = [NSPredicate predicateWithFormat:@"$my_var.employees.@count == 3"];
NSExpression * myExpr = [NSExpression expressionForKeyPath:@"$my_var.test"] ;
NSPredicate * myPredBis = [myPred predicateWithSubstitutionVariables:@{@"my_var" : myExpr}] ;
NSExpression * myExpr2 = [NSExpression expressionForKeyPath:@"self"] ;
NSPredicate * myFinalPred = [myPredBis predicateWithSubstitutionVariables:@{@"my_var": myExpr2}];
NSLog(@"%@", myFinalPred) ;
It prints
$my_var.test.employees.@count == 3
But we would like
self.test.employees.@count == 3
Why does this happen?
回答1:
This is only a partial answer, but perhaps it helps to put you on the right path.
First, substituting $my_var
by [NSExpression expressionForKeyPath:@"$my_var.test"]
does not work, because the latter expression treats $my_var
as a plain key, not as
a variable.
But you can substitute one variable by another variable, using expressionForVariable
:
NSPredicate * myPred = [NSPredicate predicateWithFormat:@"$my_var.employees.@count == 3"];
NSExpression * myExpr = [NSExpression expressionForVariable:@"another_var"] ;
NSPredicate * myPredBis = [myPred predicateWithSubstitutionVariables:@{@"my_var" : myExpr}] ;
Second, [NSExpression expressionForKeyPath:@"self"]
treats "self" as an ordinary key, not as "the" self, i.e. the object onto which the predicate is applied. You probably
want:
NSExpression * myExpr2 = [NSExpression expressionForEvaluatedObject];
instead. Now you can chain the substitution:
NSPredicate * myFinalPred = [myPredBis predicateWithSubstitutionVariables:@{@"another_var": myExpr2}];
NSLog(@"%@", myFinalPred);
Output: employees.@count == 3
(the "self" part is just not printed).
OK, here is the solution to your problem. The tricky part is the second step.
I did not find a direct way to build a key-path expression that consists of a
variable ($my_var
) combined with a normal key (test
). But it can be done
by taking the left-hand side of a predicate:
NSPredicate * myPred = [NSPredicate predicateWithFormat:@"$my_var.employees.@count == 3"];
NSLog(@"%@", myPred) ;
// $my_var.employees.@count == 3
NSExpression *myExpr = [(NSComparisonPredicate *)[NSPredicate predicateWithFormat:@"$my_var.test == 0"] leftExpression];
NSPredicate * myPredBis = [myPred predicateWithSubstitutionVariables:@{@"my_var" : myExpr}] ;
NSLog(@"%@", myPredBis) ;
// $my_var.test.employees.@count == 3
NSExpression * myExpr2 = [NSExpression expressionForEvaluatedObject];
NSPredicate * myFinalPred = [myPredBis predicateWithSubstitutionVariables:@{@"my_var": myExpr2}];
NSLog(@"%@", myFinalPred) ;
// test.employees.@count == 3
来源:https://stackoverflow.com/questions/21823339/chaining-replacements-dont-work-in-nspredicate