87212

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

Question:

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?

Answer1:

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

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 NSExpression object.</li> <li>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.</li> <li>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)</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.

Recommend

  • CMCalibratedMagneticField doesn't update
  • NSURL Always Returns Nil
  • Display Local HTML file from documents directory in a UIWebView on iPhone
  • adding zeros in objective-c string formats
  • iOS Date formatting
  • Perl keyword say is not working in version 5.14.4
  • Getting errors while using neuralnet function
  • Zend Framework + Doctrine1.2 project structure with more modules
  • How many Vertica Databases can run on a Host in the same time?
  • Why does Sencha 2 only work in Webkit browsers?
  • What is this iOS exception with NSCFType?
  • File extension of zlib zipped html page?
  • Is it possible to get the word under the mouse cursor in a ``?
  • Can my PDF ping my server when it is opened?
  • how to solve invalid conversion specifier warning in iphone app
  • Access user's phone number on iOS 7
  • GAE: Way to get reference to an HttpSession from its ID?
  • Multicolored edittext hint
  • Redux Form - Not able to type anything in input
  • How can I sort a a table with VBA with given text condition?
  • All Classes Conforming to Protocol Inherit Default Implementation
  • Java Scanner input dilemma. Automatically inputs without allowing user to type
  • Master page gives error
  • HTML download movie download link
  • How to recover from a Spring Social ExpiredAuthorizationException
  • ILMerge & Keep Assembly Name
  • Font Awesome Showing Box instead of Icons
  • Large data - storage and query
  • How can I estimate amount of memory left with calling System.gc()?
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • WOWZA + RTMP + HTML5 Playback?
  • AT Commands to Send SMS not working in Windows 8.1
  • Compare two NSDates in iPhone
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • apache spark aggregate function using min value
  • Is it possible to post an object from jquery to bottle.py?
  • Can't mass-assign protected attributes when import data from csv file
  • sending mail using smtp is too slow
  • Sorting a 2D array using the second column C++
  • Python/Django TangoWithDjango Models and Databases