开发者

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

开发者 https://www.devze.com 2023-03-31 11:32 出处:网络
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:

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?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消