NSPredicate predicateWithFormat不评估格式说明符

时间:2012-08-19 11:20:17

标签: objective-c nspredicate

我对NSPredicate的predicateWithFormat:方法有一个(对我而言)好奇的案例。

使用以下内容将两个NSPredicate实例的描述记录到控制台:

NSNumber *myNumber = [NSNumber numberWithInt:1];

NSString *predicateFormatByHand = [NSString stringWithFormat:@"self MATCHES 'chp%@_img[0-9]+\\.png'", myNumber];
NSPredicate *firstPredicate = [NSPredicate predicateWithFormat:predicateFormatByHand];

NSLog(@"firstPredicate description: %@", firstPredicate);

NSPredicate *secondPredicate = [NSPredicate predicateWithFormat:@"self MATCHES 'chp%@_img[0-9]+\\.png'", myNumber];

NSLog(@"secondPredicate description: %@", secondPredicate);

输出:

 firstPredicate description: SELF MATCHES "chp1_img[0-9]+.png"
 secondPredicate description: SELF MATCHES "chp%@_img[0-9]+.png"

我希望这些描述是一样的。

有人可以解释他们为什么不是吗?

(关注this question我已经使用嵌入式单引号的各种转义序列但是在这样做的时候继续让NSPredicate抱怨它无法解析格式字符串。我很想知道会发生什么上。)

更新:一个答案表明使用NSNumber而不是int是一个问题,所以:

NSPredicate *thirdPredicate = [NSPredicate predicateWithFormat:@"self MATCHES 'chp%d_img[0-9]+\\.png'", [myNumber intValue]];

NSLog(@"thirdPredicate description: %@", thirdPredicate);   

我最初是从这开始的,但唉,输出是一样的:

 thirdPredicate description: SELF MATCHES "chp%d_img[0-9]+.png"

(某事意味着不评估格式说明符。)

感谢。

3 个答案:

答案 0 :(得分:4)

答案很简单:NSPredicate使用的解析器假定引号内的任何内容都是字符串文字,并且不会尝试对其内容进行任何替换。你需要有一个动态字符串值,你必须在将它替换为谓词格式字符串之前构建字符串,如第一个例子中所示。

答案 1 :(得分:2)

...因为predicate不是string

对于predicate中的任何一个,您应该使用两个格式说明符100%仅安全:

  • 一个用于%K);和
  • 一个用于%@);

将{em>键 时,不能将它们格式化为predicate。这就是为什么你的第二个(和第三个)predicates没有在值中格式化的原因。

您可以格式化 ,然后将其添加到predicate,如:

NSNumber *myNumber = [NSNumber numberWithInt:1];
NSString *string = [NSString stringWithFormat:@"chp%@_img[0-9]+\\.png", myNumber];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", string];
NSLog(@"%@", predicate);

结果是:

SELF MATCHES "chp1_img[0-9]+\\.png"

...永远不要忘记我的第一句话:predicatesstrings不是一回事。

答案 2 :(得分:0)

我对

的解释
  

%@是对象值

的var arg替换
“谓词编程指南”中的

%@只能用于替换可以与核心数据对象进行比较的值。例如

NSNumber *myNumber = [NSNumber numberWithInt:1]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"count = %@", myNumber];
如果“count”是实体的Number属性,则

完全有效。它类似于SQLite预处理语句的绑定值。

如果%@可用于谓词中的常规字符串格式设置,则不需要为关键路径和值设置两个不同的格式说明符%K%@