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:
- 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 appropriateNSExpression
object. - 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. - 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 case00005
is the same thing as5
, and thus the zero padding is irrelevant) and string comparisons (in which you can just format the string yourself before giving it toNSPredicate
). (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.
精彩评论