我需要建立一个动态的NSPredicates。我发现使用字符串文件非常方便,我可以应用替换变量。这就是我在文件中所做的。
start<=$START AND end>=$END
这是驻留在实用程序方法中的代码片段:
-(NSPredicate*)predicateWithName:(NSString*)name andVariables:(NSDictionary*)dict {
NSURL *queryFile = [[NSBundle mainBundle] URLForResource:name withExtension:@"query"];
//...
NSString *query = [NSString stringWithContentsOfURL:queryFile encoding:NSStringEncodingConversionAllowLossy error:&err];
NSPredicate *predicate = [NSPredicate predicateWithFormat:query];
return [predicate predicateWithSubstitutionVariables:dict];
}
一切都运行得很好,但是现在我需要添加动态字段,基于某些条件我想查询特定字段,但我找不到实现此目的的方法。查询文件可能变为:
start<=$START AND end>=$END AND $FIELD_NAME==1
$ FIELD_NAME名称将替换为引号,但查询无效。我知道我可以使用%K作为密钥,但似乎没有办法用字典做这个。
感谢
答案 0 :(得分:2)
所以,我知道没有内置的方法可以做到这一点。但是,写自己很简单。您可以轻松编写一个NSPredicate
类别方法,用一个关键路径表达式替换以KEY_
开头的变量,如下所示:
- (NSPredicate *)predicateWithEnhancedSubstitutionVariables:(NSDictionary *)vars {
if ([self isKindOfClass:[NSCompoundPredicate class]]) {
// recurse for compound predicates
NSCompoundPredicate *compound = (NSCompoundPredicate *)self;
NSMutableArray *subpredicates = [NSMutableArray array];
for (NSPredicate *subpredicate in [compound subpredicates]) {
NSPredicate *new = [subpredicate predicateWithEnhancedSubstitutionVariables:vars];
[subpredicates addObject:new];
}
return [[[NSCompoundPredicate alloc] initWithType:[compound compoundPredicateType]
subpredicates:subpredicates] autorelease];
} else {
NSPredicate *final = self;
// on comparison predicates, pull out the left and right expressions
NSComparisonPredicate *comparison = (NSComparisonPredicate *)self;
NSExpression *left = [comparison leftExpression];
// substitute, if appropriate
if ([left expressionType] == NSVariableExpressionType) {
NSString *variable = [left variable];
if ([variable hasPrefix:@"KEY_"]) {
NSString *replacement = [vars objectForKey:variable];
if (replacement) {
left = [NSExpression expressionForKeyPath:replacement];
}
}
}
// substitute, if appropriate
NSExpression *right = [comparison rightExpression];
if ([right expressionType] == NSVariableExpressionType) {
NSString *variable = [right variable];
if ([variable hasPrefix:@"KEY_"]) {
NSString *replacement = [vars objectForKey:variable];
if (replacement) {
right = [NSExpression expressionForKeyPath:replacement];
}
}
}
// build and return the appropriate comparison predicate
if (left != [comparison leftExpression] || right != [comparison rightExpression]) {
if ([comparison customSelector] != NULL) {
final = [NSComparisonPredicate predicateWithLeftExpression:left
rightExpression:right
customSelector:[comparison customSelector]];
} else {
final = [NSComparisonPredicate predicateWithLeftExpression:left
rightExpression:right
modifier:[comparison comparisonPredicateModifier]
type:[comparison predicateOperatorType]
options:[comparison options]];
}
}
return [final predicateWithSubstitutionVariables:vars];
}
}
有了这个,你应该能够做到:
NSPredicate *p = [NSPredicate predicateWithFormat:@"$KEY_DATE = $DATE"];
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:@"myDateProperty", @"KEY_DATE", aDate, @"date", nil];
p = [p predicateWithEnhancedSubstitutionVariables:d];
然后回复一个谓词,好像你已经完成了:
NSPredicate *p = [NSPredicate predicateWithFormat:@"myDateProperty = %@", aDate];
警告:在浏览器中键入,未编译,yadda yadda