Last active
February 6, 2022 14:47
-
-
Save michaelochs/42256e190d3d230f7f24052159dceb0b to your computer and use it in GitHub Desktop.
As a follow up for https://gist.github.com/michaelochs/f106b5c42aafe6bed74ac5dab82281c4 this is what's going on under the hood!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface MyStringProxy : NSProxy | |
@property (nonatomic) NSString *target; | |
@end | |
@implementation MyStringProxy | |
- (BOOL)respondsToSelector:(SEL)aSelector { | |
if (aSelector == NSSelectorFromString(@"_dynamicContextEvaluation:patternString:")) { | |
return YES; | |
} else { | |
return [self.target respondsToSelector:aSelector]; | |
} | |
} | |
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { | |
return [self.target methodSignatureForSelector:sel]; | |
} | |
- (void)forwardInvocation:(NSInvocation *)invocation { | |
[invocation invokeWithTarget:self.target]; | |
} | |
- (NSString *)_dynamicContextEvaluation:(NSString *)context patternString:(NSString *)pattern { | |
// Do a FORWARD search as it seems the same pattern is used for all the replacements, one by one. | |
// So we are looking for the first appearance of `pattern` and return our replacement. The next | |
// placeholder will see the partially replaced string and again looks for the first appearance of | |
// `pattern` and so on... | |
NSRange range = [context rangeOfString:pattern]; | |
if (range.location == 0) { | |
return [NSString stringWithFormat:@"First(%@)", self.target]; | |
} else if (range.location + range.length == context.length) { | |
return [NSString stringWithFormat:@"last(%@)", self.target]; | |
} else { | |
return [NSString stringWithFormat:@"middle(%@)", self.target]; | |
} | |
} | |
@end | |
@implementation AppDelegate | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | |
MyStringProxy *proxy = [MyStringProxy alloc]; | |
proxy.target = @"something"; | |
NSString *test = [NSString stringWithFormat:@"%@ %@ %@", proxy, proxy, proxy]; | |
NSLog(@"%@", test); // "First(something) middle(something) last(something)" | |
return YES; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment