2012-04-17 164 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];