2015-09-15 57 views
2

我想知道是否有一種方法來構建一個謂詞並動態指定要使用哪個比較器?例如,我試過,但它崩潰:NSPredicate中的動態比較器

NSPredicate *validPredicate = [NSPredicate predicateWithFormat:@"%K %@ %@", NSStringFromSelector(@selector(expirationDate)), isValid ? @"<" : @">",[NSDate date]]; 

,但如果我硬編碼字符串中的比較它不會崩潰:

NSPredicate *validPredicate = [NSPredicate predicateWithFormat:@"%K < %@", NSStringFromSelector(@selector(expirationDate)), [NSDate date]]; 

難道還有比這樣做的最佳方式:

NSPredicate * validPredicate = nil; 

if (isValid) { 
    validPredicate = [NSPredicate predicateWithFormat:@"%K > %@", NSStringFromSelector(@selector(expirationDate)), [NSDate date]]; 
} else { 
    validPredicate = [NSPredicate predicateWithFormat:@"%K < %@", NSStringFromSelector(@selector(expirationDate)), [NSDate date]]; 
} 

回答

0

我不確定爲什麼解析第一個示例時出現錯誤,但是如何首先構建格式:

NSString *format = [NSString stringWithFormat:@"%%K %@ %%@", isValid ? @"<" : @">"]; 
NSPredicate *validPredicate = [NSPredicate predicateWithFormat:format, NSStringFromSelector(@selector(expirationDate)), [NSDate date]]; 

(這是較少的代碼,該if,但我想這取決於你的「最佳」。的定義)

0

從技術上講,正確的方式做到這一點是使用上NSComparisonPredicate初始化。使用動態生成的格式字符串可能會起作用,但它很脆弱。

NSPredicateOperatorType comparison = isValid ? NSGreaterThanPredicateOperatorType : NSLessThanPredicateOperatorType; 

NSExpression *expirationDate = [NSExpression expressionForKeyPath:@"expirationDate"]; 
NSExpression *date = [NSExpression expressionForConstantValue:[NSDate date]]; 
validPredicate = [[NSComparisonPredicate alloc] initWithLeftExpression:expirationDate 
                 rightExpression:date 
                   modifier:NSDirectPredicateModifier 
                    type:comparison 
                   options:0];