I have an array with file names and I want to find all the names that end with e.g. <em>00001.trc</em> 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?
predicateWithFormat: is not quite the same as
It's different for a couple major reasons:<ol><li>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
NSExpressionobject.</li> <li>It has to support a format specifier that
%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.</li> <li>Using formatting constraints (I'm not sure what the proper term is) like the
%05disn't supported. For one, it doesn't make sense.
NSPredicatedoes numerical comparisons (in which case
00005is 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)</li> </ol>
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.