Skip to content

Instantly share code, notes, and snippets.

@janodev
Created November 30, 2012 13:50
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save janodev/4175830 to your computer and use it in GitHub Desktop.
Save janodev/4175830 to your computer and use it in GitHub Desktop.
Dynamic properties
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic,strong) NSMutableDictionary *properties;
@end
@implementation Person
-(id) init {
self = [super init];
if (self){
_properties = [NSMutableDictionary new];
}
return self;
}
// generic getter
static id propertyIMP(id self, SEL _cmd) {
return [[self properties] valueForKey:NSStringFromSelector(_cmd)];
}
// generic setter
static void setPropertyIMP(id self, SEL _cmd, id aValue) {
id value = [aValue copy];
NSMutableString *key = [NSStringFromSelector(_cmd) mutableCopy];
// delete "set" and ":" and lowercase first letter
[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]];
[[self properties] 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 setName:@"Jon"];
NSLog(@"%@",[p name]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment