2012-04-17 163 views
2

我試圖建立一個查詢字符串或斷言,但我不斷收到此錯誤,NSPredicate:「無法解析格式字符串'%@'」?

基本上我不明白的是,這工作得很好:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(name contains[cd] 'o')"]; 

但這:

NSString *predString = @"(name contains[cd] 'o')"; 
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%@", predString]; 

拋出這個:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "%@"'

回答

12

%@不是謂詞格式,它是一種字符串格式。

NSPredicate *pred = [NSPredicate predicateWithFormat:predString]; 
+0

是的,只是創建格式化的字符串,並通過在 – 2012-04-17 21:00:37

+0

這不是一個適當的解決方案的問題。它會打開你的代碼多達各種萬一格式字符串注入攻擊'predString'包含用戶提供的數據(例如,'帳戶==「用戶%K%@」'和'用戶%K%@'是攻擊者提供的數據)。你應該永遠不要在任何'... withFormat:'方法中使用除了常量字符串之外的任何字符串。 – user8472 2014-11-06 14:23:39

0

正如指出的那樣,%@不能在謂詞構造中的任何地方使用。但是能夠提前構造謂詞會很有用。您可以使用的#define來定義所有或至少它的恆定部分:

#define kPredicateStr_MovieItem_MoviesInCatalog @"((wishList == NO) AND ((tvEpisode == NO) || (tvEpisode == YES AND (ANY tvSeries.genres.name LIKE 'TV Movie'))))" 

然後要麼提供其作爲-是:

itemsViewController.predicate = [NSPredicate predicateWithFormat:kPredicateStr_MovieItem_MoviesInCatalog]; 

或添加到它:

NSString *predStr = [NSString stringWithFormat:@"%@ AND (%@ CONTAINS \"%@\")", kPredicateStr_MovieItem_MoviesInCatalog, titleForSearch, searchString]; 

    predicate = [NSPredicate predicateWithFormat:predStr];