predicateWithFormat vs stringWithFormat: is the former supposed to do the same as the latter?

半城伤御伤魂 提交于 2019-12-23 18:23:27

问题


I have an array with file names and I want to find all the names that end with e.g. 00001.trc when traceNum is 1. I tried this:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum];

and my predicate was SELF ENDSWITH "%05d.trc" instead of SELF ENDSWITH "00001.trc"

I tried this:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.trc%@", @"\"", traceNum, @"\""];

and I got an exception: Unable to parse the format string "SELF ENDSWITH %@%05d.trc%@".

So I tried this:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum]];

and it works.

So do I really need stringWithFormat in addition to predicateWithFormat or is there something I'm not doing correctly in creating my predicate?


回答1:


You're correct; predicateWithFormat: is not quite the same as stringWithFormat:.

It's different for a couple major reasons:

  1. It's not actually creating a new string. It's just looking through the format string and seeing what the next thing to substitute is, popping that off the va_list, and boxing it up into the appropriate NSExpression object.
  2. It has to support a format specifier that NSString doesn't: %K. This is how you substitute in a key path. If you tried to substitute in the name of a property using %@, it would actually be interpreted as a literal string, and not as a property name.
  3. Using formatting constraints (I'm not sure what the proper term is) like the 05 in %05d isn't supported. For one, it doesn't make sense. NSPredicate does numerical comparisons (in which case 00005 is the same thing as 5, and thus the zero padding is irrelevant) and string comparisons (in which you can just format the string yourself before giving it to NSPredicate). (It does other comparisons, like collection operations, but I'm skipping those for now)

So, how do you do what you're trying to do? The best way would be like this:

NSString *trace = [NSString stringWithFormat:@"%05d.trc", traceNum];
NSPredicate *p = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", trace];

This way you can do all the formatting you want, but still use the more correct approach of passing a constant string as the predicate format.



来源:https://stackoverflow.com/questions/7238631/predicatewithformat-vs-stringwithformat-is-the-former-supposed-to-do-the-same-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!