문제

내가 생각하고자하는 특정 접근법에 대한 피드백에 감사드립니다. 시나리오는 다음과 같습니다.

X 및 Y 좌표, 높이 및 너비와 같은 여러 속성이있는 객체 (mobject라고 부르겠습니다)가 있습니다. 속성은 KVC 가이드 라인 (mobject.x; mobject.height 등)에 따라 명명되었습니다. 다음 과제는이 mobject를 설명하는 XML 파일로 읽는 것입니다. 불행히도 XML 요소의 이름은 x와 y, 높이 및 너비 (대문자에 유의)입니다.

이상적으로 XML 요소는 Mobject의 속성과 일치합니다. 이 경우 KVC를 사용하고 전체 코드를 피할 수 있습니다.

for (xmlProperty in xmlElement)
{
    [MObject setValue:xmlProperty.value forKey:xmlProperty.name].
}

이에 접근하는 한 가지 방법은 케이스에 민감한 키를 사용하는 것입니다. 어디서부터 시작할까요? 다른 더 나은 솔루션이 있습니까?

제안은 대단히 감사했습니다.

도움이 되었습니까?

해결책

무시하지 마십시오 -[NSObject valueForKey:] 그리고 -[NSObject setValue:forKey:] 당신이 전혀 도움이 될 수 있다면.

가장 좋은 방법은 XML 파일에서 얻은 키를 즉석에서 변환하는 것입니다. 별도의 메소드를 사용하여 변환을 수행하면 이름 캐시를 속성 키로 유지할 수 있으므로 각 변환 만 한 번만 수행하면됩니다.

- (NSString *)keyForName:(NSString *)name {
    // _nameToKeyCache is an NSMutableDictionary that caches the key
    // generated for a given name so it's only generated once per name
    NSString *key = [_nameToKeyCache objectForKey:name];
    if (key == nil) {
        // ...generate key...
        [_nameToKeyCache setObject:key forKey:name];
    }
    return key;
}

- (void)foo:xmlElement {
    for (xmlProperty in xmlElement) {
        [myObject setValue:xmlProperty.value forKey:[self keyForName:xmlProperty.name]].
    }
}

다른 팁

NSString을 사용할 수 있습니다 lowercaseString XML 키 이름을 소문자로 변환하려면 도움이되면 도움이됩니다.

우세하다 -valueForUndefinedKey: 그리고 -setValue:forUndefinedKey:

대문자가 다른 키를 찾으면 사용하십시오. 그렇지 않으면 전화하십시오. super.

우세하다 -valueForKey: 그리고 -setValue:forKey:.

당신은 아마 당신이 인식하는 키 (요소/속성 이름) 만 허용해야하며 super 다른 키를 위해.

그래서 저는 Chris Hanson의 제안을 구현했으며 여기에 내가 한 것이 있습니다. 나는 이것을 Utils 수업에 넣었다. 우리가 조심하는 각 클래스마다 사전을 유지합니다. 아마 약간의 리팩토링을 사용할 수 있지만 지금까지 나에게 매우 잘 작동했습니다.

static NSMutableDictionary *keyCache;

+ (NSString *)keyForClass:(Class)klass column:(NSString *)column {
    if (!keyCache) { keyCache = [NSMutableDictionary dictionary]; }

    NSString *className = NSStringFromClass(klass);

    NSMutableDictionary *tableKeyCache = [keyCache objectForKey:className];

    if (!tableKeyCache) {
        tableKeyCache = [NSMutableDictionary dictionary];

        unsigned int numMethods = 0;
        Method *methods = class_copyMethodList(klass, &numMethods);
        NSMutableArray * selectors = [NSMutableArray array];
        for (int i = 0; i < numMethods; ++i) {
            SEL selector = method_getName(methods[i]);
            [selectors addObject:NSStringFromSelector(selector)];
        }
        [tableKeyCache setValue:selectors forKey:@"allSelectors"];
        free(methods);
        [keyCache setValue:tableKeyCache forKey:className];
    }

    NSString *keyToReturn = [tableKeyCache valueForKey:column];
    if (!keyToReturn) {
        for (NSString *columnKey in [tableKeyCache valueForKey:@"allSelectors"]) {
            if ( [column caseInsensitiveCompare:columnKey] == NSOrderedSame) {
                [tableKeyCache setValue:columnKey forKey:column];
                keyToReturn = columnKey;
                break;
            }
        }
    }

    if (!keyToReturn) { // Taking a guess here...
        NSLog(@"Selector not found for %@: %@ ", className, column);
        keyToReturn = [Utils keyForClass:[klass superclass] column:column];
    }

    return keyToReturn;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top