Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dynamic get/set. Watch it, I'm using [[NSThread currentThread] threadDictionary] for thread-safe access.
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface Person : NSObject
@end
@implementation Person
@end
@interface Person(dynamicProperties)
@end
@implementation Person(dynamicProperties)
static id propertyIMP(id self, SEL _cmd) {
return [[[NSThread currentThread] threadDictionary] valueForKey:NSStringFromSelector(_cmd)];
}
static void setPropertyIMP(id self, SEL _cmd, id aValue) {
id value = [aValue copy];
NSMutableString *key = [NSStringFromSelector(_cmd) mutableCopy];
[key deleteCharactersInRange:NSMakeRange(0, 3)];
[key deleteCharactersInRange:NSMakeRange([key length] - 1, 1)];
NSString *firstChar = [key substringToIndex:1];
[key replaceCharactersInRange:NSMakeRange(0, 1) withString:[firstChar lowercaseString]];
[[[NSThread currentThread] threadDictionary] setValue:value forKey:key];
}
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
if ([NSStringFromSelector(aSEL) hasPrefix:@"set"]) {
class_addMethod([self class], aSEL, (IMP)setPropertyIMP, "v@:@");
} else {
class_addMethod([self class], aSEL,(IMP)propertyIMP, "@@:");
}
return YES;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
Person *p = [Person new];
[p performSelector:@selector(setName:) withObject:@"Jon"];
NSLog(@"%@",[p performSelector:@selector(name)]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment