2013-05-17 51 views
1

我試圖創建下面的謂詞我可以通過格式字符串將運算符傳遞給NSPredicate嗎?

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

varNamevarDate的的NSString和NSDate的對象分別。該operator變量聲明,如下所示:

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

基本上我想創建謂詞時節省幾行。我知道我可以根據direction的值創建不同的謂詞,但這個用例讓我思考。

現在這個當前的方法崩潰了,所以我不認爲它是可能的。我想知道是否有其他人有幸運。

回答

1

您不能這樣做,因爲格式字符串與提供的參數不同,因爲在提供的參數將在處理格式字符串以生成有效的可分析謂詞字符串時引用。

+0

必須等待6分鐘,接受這個答案。對不起,如果我忘記了,謝謝你的迴應,更有意義。 – atreat

+0

3個月後... – atreat

+0

下面的代碼由terphi – atreat

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]]; 
+0

好吧,這不會像你說的那樣「保存幾條線」,但是如何在運行時動態地創建一個謂詞可能會很有趣。 –

+0

試圖保存代碼行,所以我可能不會使用這個,但絕對很高興我知道它的可能性。如果要動態創建謂詞 – atreat

2

我意識到這是不超過運的有關使用不同的謂詞字符串聲明根本不同的,但你可以動態生成謂詞字符串:

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]; 
1

真的有這樣做更有效的方式:

NSString *dateOperator = (direction == kPageDirectionForward) ? @">" : @"<"; 
NSString *stringPredicate=[NSString stringWithFormat:@"%%K != %%@ AND %%K %@ %%@", dateOperator]; 

NSPredicate *yourPredicate=[NSPredicate stringPredicate argumentArray:@[@"name",varName,@"date",varDate]]; 
+0

這看起來像是正確的答案這確實是最明確和最簡潔的答案。 – isaac

相關問題