Created
May 29, 2010 01:52
-
-
Save adamawolf/417955 to your computer and use it in GitHub Desktop.
An Objective-C data structure that accepts setVariableName: and variableName messages without declaring a variableName property.
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
#import "Remap.h" | |
//to suppress warnings | |
RemapProperty(sampleText); | |
RemapProperty(sampleDict); | |
#define kKey_SampleText @"sampleTextKey" | |
int main() | |
{ | |
Remap * remap = [[Remap alloc] init]; | |
[remap setSampleText:@"example"]; | |
[remap setSampleDict:[NSDictionary dictionaryWithObject:[remap sampleText] forKey:kKey_SampleText]]; | |
NSLog(@"%@", [[remap sampleDict] objectForKey:kKey_SampleText]); | |
return 1; | |
} |
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
// | |
// Remap.m | |
// | |
// Created by Adam Wolf on 5/24/10. | |
// | |
#import "Remap.h" | |
@interface Remap () | |
@property (nonatomic, retain) NSMutableDictionary * _data; | |
@end | |
@implementation Remap | |
@synthesize _data; | |
- (void) dealloc | |
{ | |
relnil(_data); | |
[super dealloc]; | |
} | |
- (id) init | |
{ | |
self = [super init]; | |
if (self != nil) { | |
NSMutableDictionary * dict = [[NSMutableDictionary alloc] init]; | |
[self set_data:dict]; | |
relnil(dict); | |
} | |
return self; | |
} | |
- (void)forwardInvocation:(NSInvocation *)anInvocation | |
{ | |
NSString * selectorName = NSStringFromSelector([anInvocation selector]); | |
NSRange range = [selectorName rangeOfString:@"set"]; | |
NSInteger numArguments = [[anInvocation methodSignature] numberOfArguments]; | |
if (range.location == 0 && numArguments == 4) | |
{ | |
//setter | |
[anInvocation setSelector:@selector(setData:withKey:)]; | |
[anInvocation setArgument:&selectorName atIndex:3]; | |
[anInvocation invokeWithTarget:self]; | |
} | |
else if (numArguments == 3) | |
{ | |
[anInvocation setSelector:@selector(getDataWithKey:)]; | |
[anInvocation setArgument:&selectorName atIndex:2]; | |
[anInvocation invokeWithTarget:self]; | |
} | |
} | |
- (NSMethodSignature *) methodSignatureForSelector:(SEL) aSelector | |
{ | |
NSString * selectorName = NSStringFromSelector(aSelector); | |
NSMethodSignature * sig = [super methodSignatureForSelector:aSelector]; | |
if (sig == nil) | |
{ | |
NSRange range = [selectorName rangeOfString:@"set"]; | |
if (range.location == 0) | |
{ | |
sig = [self methodSignatureForSelector:@selector(setData:withKey:)]; | |
} | |
else | |
{ | |
sig = [self methodSignatureForSelector:@selector(getDataWithKey:)]; | |
} | |
} | |
return sig; | |
} | |
- (NSObject *) getDataWithKey: (NSString *) key | |
{ | |
NSObject * returnValue = [[self _data] objectForKey:key]; | |
return returnValue; | |
} | |
- (void) setData: (NSObject *) data withKey:(NSString *)key | |
{ | |
if (key && [key length] >= 5 && data) | |
{ | |
NSRange range; | |
range.length = 1; | |
range.location = 3; | |
NSString * firstChar = [key substringWithRange:range]; | |
firstChar = [firstChar lowercaseString]; | |
range.length = [key length] - 5; // the 4 we have processed plus the trailing : | |
range.location = 4; | |
NSString * adjustedKey = [NSString stringWithFormat:@"%@%@", firstChar, [key substringWithRange:range]]; | |
[[self _data] setObject:data forKey:adjustedKey]; | |
} | |
else | |
{ | |
//assert? | |
} | |
} | |
@end |
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
// | |
// Remap.h | |
// | |
// Created by Adam Wolf on 5/24/10. | |
// | |
// Meant as a wrapper around NSMutableDictionary to retrieve any arbitrary | |
// ivar access and store any arbitrary ivar set, regardless of if the ivar is | |
// define in the object. | |
#import <Foundation/Foundation.h> | |
@interface Remap : NSObject { | |
@private | |
NSMutableDictionary * _data; | |
} | |
#define RemapProperty(PROP) \ | |
@interface Remap(PROP) \ | |
@property (nonatomic, retain) id PROP; \ | |
@end \ | |
@implementation Remap(PROP) \ | |
@dynamic PROP; \ | |
@end | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment