my solution is to use a pair of functions which cleans the typed expression as best it can but then calmly handles errors on any remaining malformed input
You’ve disable ARC on this Objective-C code, right?
Also, you kinda missed my point about placeholders. Consider this code:
@import Foundation;
int main(int argc, char **argv) {
NSExpression * ex = [NSExpression expressionWithFormat:@"(1 + %@)"];
return ex != nil ? 0 : 1;
}
On my machine this crashes with a memory access exception — a type of machine exception — which you can’t reasonably catch in any language. That’s because the %@
placeholder expects you to supply another argument with the value for that placeholder.
You can prevent the crash by calling the variant that takes an arguments array:
NSExpression * ex = [NSExpression expressionWithFormat:@"(1 + %@)" argumentArray:@[]];
This turns the crash into a language exception, which you’re already catching.
You also missed my point about key paths. Consider this code:
NSExpression * ex = [NSExpression expressionWithFormat:@"1.release" argumentArray:@[]];
id v = [ex expressionValueWithObject:nil context:nil];
Here I’m calling the Objective-C -release
method via a key path. NSExpression
expression explicitly forbids this and traps. That trap is actually a machine exception which you can’t reasonably catch in any language.
So, to sum up:
-
NSExpression
is not designed to be used with an arbitrary user-supplied format string.
-
You may be able to patch some of the holes, but you’ll almost certainly miss some.
-
Rather than continue down this path, I recommend that you write or acquire your own expression parsing code [1].
And that brings me to:
perhaps with the advent of math in apps like Notes there will be a Swift solution in the future.
I recommend that you file an enhancement request for that. Honestly, I recommend that you file two ERs:
-
One against NSExpression
, asking for Swift-safe version of +expressionWithFormat:
.
-
One for a real Swift API.
Please post your bug numbers, just for the record.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] If you’re looking for something cool, and your product is compatible with its licence, check out SoulverCore.