【问题标题】:Case-insensitive KVC in Cocoa? [closed]可可中不区分大小写的KVC? [关闭]
【发布时间】:2010-09-25 01:12:36
【问题描述】:

对于我正在考虑使用的特定方法的一些反馈,我将不胜感激。场景如下。

我有一个对象(我们称之为 MObject),它有许多属性,比如 x 和 y 坐标、高度和宽度。这些属性根据 KVC 指南(MObject.x;MObject.height 等)命名。我的下一个任务是读入描述这个 MObject 的 XML 文件。不幸的是,XML 元素的名称不同——X 和 Y、高度和宽度(注意大写)。

理想情况下,XML 元素应与 MObject 的属性相匹配。在这种情况下,我可以使用 KVC 并避免大量代码:

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

解决此问题的一种方法是使用不区分大小写的键。我会从哪里开始呢?还有其他更好的解决方案吗?

非常感谢您的建议。

【问题讨论】:

    标签: cocoa key-value-observing key-value-coding


    【解决方案1】:

    如果您能提供帮助,请不要覆盖 -[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]].
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 非常简单的解决方案。干得好!
      • 这可行,我想唯一的问题是命名约定。
      【解决方案3】:

      覆盖 -valueForUndefinedKey:-setValue:forUndefinedKey:

      如果您发现有不同大小写的密钥,请使用它,否则请致电super

      【讨论】:

        【解决方案4】:

        覆盖-valueForKey:-setValue:forKey:

        您应该只接受您认识的键(元素/属性名称),并致电super 获取其他键。

        【讨论】:

          【解决方案5】:

          所以我实施了 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;
          }
          

          【讨论】:

          • 另外,别忘了#import
          猜你喜欢
          • 1970-01-01
          • 2013-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多