Skip to content

Instantly share code, notes, and snippets.

@1ec5
Last active January 4, 2018 01:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1ec5/1403a1b35929fc68fb2519902c012f81 to your computer and use it in GitHub Desktop.
Save 1ec5/1403a1b35929fc68fb2519902c012f81 to your computer and use it in GitHub Desktop.
Freedom of NSExpression
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
/**
Joins the given components into a single string by concatenating each component
in order.
*/
NSString *MGLJoinComponents(Class self, SEL _cmd, NSArray<NSString *> *components) {
return [components componentsJoinedByString:@""];
}
/**
Adds to NSExpression’s built-in repertoire of functions.
*/
void endowExpressions() {
// NSExpression’s built-in functions are backed by class methods on a
// private class, so use a function expression to get at the class.
// http://funwithobjc.tumblr.com/post/2922267976/using-custom-functions-with-nsexpression
NSExpression *functionExpression = [NSExpression expressionWithFormat:@"sum({})"];
NSString *className = NSStringFromClass([functionExpression.operand.constantValue class]);
// Effectively categorize the class with some extra class methods.
Class NSPredicateUtilities = objc_getMetaClass(className.UTF8String);
#pragma clang push
#pragma clang diagnostic ignored "-Wundeclared-selector"
class_addMethod(NSPredicateUtilities, @selector(mgl_join:), (IMP)MGLJoinComponents, "@@:@");
#pragma clang pop
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
endowExpressions();
NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_join({age, 'McDonald'})"];
NSString *value = [expression expressionValueWithObject:@{@"age": @"Old"} context:nil];
NSCAssert([value isEqualToString:@"OldMcDonald"], @"Evaluated expression should concatenate the strings.");
}
return 0;
}
@akitchen
Copy link

akitchen commented Jan 4, 2018

That’s pretty interesting!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment