적어도 두 가지 방법이 있습니다.
사용 objectForKeyedSubscript:
및 첨자
setObject:forKeyedSubscript:
@property (nonatomic,strong) NSMutableDictionary *properties;
- (id)objectForKeyedSubscript:(id)key {
return [[self properties] valueForKey:[NSString stringWithFormat:@"%@",key]];
}
- (void)setObject:(id)object forKeyedSubscript:(id <NSCopying>)key {
[[self properties] setValue:object forKey:[NSString stringWithFormat:@"%@",key]];
}
Person *p = [Person new];
p[@"name"] = @"Jon";
NSLog(@"%@",p[@"name"]);
resolveInstanceMethod :
이 모든 방법에 대한 런타임에 의해 objc_sendMsg을 실행 :
아래쪽을 보면 resolveInstanceMethod:
으로 메쏘드 호출을 원하는 방향으로 리디렉션 할 수 있습니다. 클래스에 요청 메소드를 추가 resolveInstanceMethod:
을 구현 한 후
// 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];
}
그리고 : 귀하의 질문에 대답하기 위해, 당신은 보이는 최대 값을 사전에 바르에 일반적인 getter 및 setter를 작성해야합니다.
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
if ([NSStringFromSelector(aSEL) hasPrefix:@"set"]) {
class_addMethod([self class], aSEL, (IMP)setPropertyIMP, "[email protected]:@");
} else {
class_addMethod([self class], aSEL,(IMP)propertyIMP, "@@:");
}
return YES;
}
당신은 또한 그런 다음있는 NSInvocation에 싸여 forwardInvocation:
에 전달되는 방법에 대한 NSMethodSignature를 반환,하지만 방법을 추가하는 것은 빠르다 수 있습니다.
Here is a gist CodeRunner에서 실행됩니다. myClass["anyProperty"]
호출은 처리하지 않습니다.
예, 가능합니다. –
(세 가지 기본 메커니즘이 있습니다 : 1) 실제로 클래스에 메소드를 추가합니다. 2) "인식 할 수없는 메시지"오류를 가로 채서 구현을 제공합니다. 3) 속성에 setter 및 getter를 가로채는 특정 방법이 있습니다. 그러나 나는 세부 사항을 가지고 있지 않다.) –