Cocoa 中不区分大小写的 KVC?

发布于 2024-07-10 05:08:21 字数 1453 浏览 12 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ゞ花落谁相伴 2024-07-17 05:08:21

如果可以的话,不要覆盖 -[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]].
    }
}

Don't override -[NSObject valueForKey:] and -[NSObject setValue:forKey:] if you can at all help it.

Your best bet would be to convert the keys you get from the XML file on the fly. Use a separate method to do the conversion and you can also maintain a cache of names to property keys, so you only need to do each conversion once.

- (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]].
    }
}
无人问我粥可暖 2024-07-17 05:08:21

如果有帮助的话,您可以使用 NSString 的 lowercaseString 将 XML 键名称转换为小写。

You can use NSString's lowercaseString to convert the XML key name to lowercase, if that helps.

十年不长 2024-07-17 05:08:21

覆盖 -valueForUndefinedKey:-setValue:forUndefineKey:

如果您发现具有不同大小写的键,请使用它,否则调用 super

Override -valueForUndefinedKey: and -setValue:forUndefinedKey:

If you find a key with a different capitalization use it, otherwise call up to super.

单调的奢华 2024-07-17 05:08:21

覆盖 -valueForKey:-setValue:forKey:

您可能应该只接受您识别的键(元素/属性名称),并为其他键调用 super

Override -valueForKey: and -setValue:forKey:.

You should probably only accept keys (element/attribute names) you recognize, and call up to super for other keys.

两个我 2024-07-17 05:08:21

所以我实施了克里斯·汉森的建议,这就是我的最终结果。 我把它放在我的 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;
}

So I implemented Chris Hanson's suggestion and here's what I ended up with. I put this in my Utils class. It keeps a dictionary for each class that we lookup. It could probably use a little refactoring but it has worked very well for me so far.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文