배경 : 내 iPhone 및 iPad 코드에 NSDictionary 개체를 많이 사용합니다. 나는이 상태 사전에 키를 가져 오거나 설정하는 자세한 방법에 질 렸습니다.Objective-C의 자바 스크립트 스타일 개체
그럼 약간 실험 : 방금 내가 Remap을 호출하는 클래스를 만들었습니다.
임의의 집합 [VariableName] :(NSObject *) obj 선택자를 가져 와서 obj를 내부 NSMutableDictionary 키 [vairableName] 아래에 삽입 할 함수에 전달합니다.
Remap은 임의의 [variableName] selector를 (0 인수) 사용하고 NSMutableDictionary에 매핑 된 NSObject를 [variableName] 키 아래에 반환합니다.
testNumber, testString 또는 testDict 속성 중 실제로 Remap에 정의 된 것이 없습니다.
미친 것? 그것은 작동합니다 ... 내 유일한 질문은 입니다 어떻게 할 수 있습니다 "응답하지 않을 수 있습니다"Remap에 대한 액세스에 대한 경고?
P. : 메시지 포워딩이 매우 비효율적이기 때문에 아마도 이것을 폐지하고 매크로를 사용하게 될 것입니다 ...하지만 Remap을 사용하면 다른 문제를 볼 수 있습니까? 여기
호기심 사람들을 위해 다시 매핑의하는 .m이다 :#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 = [NSString stringWithUTF8String: sel_getName([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 = [NSString stringWithUTF8String: sel_getName(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 training :
range.location = 4;
NSString * adjustedKey = [NSString stringWithFormat:@"%@%@", firstChar, [key substringWithRange:range]];
[[self _data] setObject:data forKey:adjustedKey];
}
else
{
//assert?
}
}
@end
사이드 노트와 마찬가지로 NSStrings에서 NSSelectorFromString을 사용하여 셀렉터를 얻을 수 있으며 NSString은 NSStringFromSelector로 셀렉터에서 가져올 수 있습니다. – dreamlax
@deamlax 아, 전화하세요. 나는 그것을 바꿀 것이다, 감사 – awolf