【问题标题】:Coercing a KVC type强制 KVC 类型
【发布时间】:2011-07-17 16:53:53
【问题描述】:

我想解析 XML 以填充 KVC 兼容的对象,但是我的解析器非常笨,它只是从 XML 属性/标签中组装 NSStrings 并尝试通过 KVC 设置它们。

这适用于实际的字符串和数字(​​我相信),但我还需要设置日期。问题显然是解析器不知道字符串代表一个日期,它试图使用 vanilla KVC 调用来处理它 - 之后 KVC 框架抱怨类型不匹配(在日期字段上设置一个字符串)。

是否有一种编程方式来“拦截”对 KVC 框架的调用,以便我可以更改正在设置的数据(通过 NSDateFormatter 运行日期字符串)?

我可以在解析器中加入一些智能,但在这样做之前,对于这类问题还有其他众所周知的解决方案吗?

【问题讨论】:

    标签: cocoa ios macos cocoa-bindings


    【解决方案1】:

    这可能不是完美的解决方案,但是...我想分享我的想法;)

    所以,首先,看看这里:Key-Value Coding - Validation。该文档描述了一种在通过 KVC 设置变量时验证变量的简洁方法。您可以通过以下方式利用此优势:

    1. 首先为您的类变量实现 KV 验证方法
    2. 设定您的价值
    3. 在您的验证方法中检查它是否是日期/字符串/任何您想要的 - 并将其更改为正确的类型。

    这应该提供一个干净的实现来确保正确的类型。

    干杯, 帕维尔

    【讨论】:

    • +1 我想我实际上可能更喜欢使用验证来回答我的问题。如果有几个属性需要强制转换,它肯定会使代码更整洁。
    • 我看到了这个功能......但没有发现我实际上可以替换该对象。不错的电话。这似乎也是在字段级别实现的,即:没有字段名称比较/查找 (validate:error:) 我是否需要管理要替换的对象的内存?我打赌我需要自动释放新的 NSDate ......尤其是如果它被设置在 (nonatomic,retain) 属性上。唯一的另一个问题是该字段上的某些集合可能不需要转换为日期(它们已经是)。我将尝试模拟性能测试。再次感谢!
    【解决方案2】:

    使用 KVC,一切都通过 setValue:forKey: 的默认实现,它调用适当的 mutator 方法 (as described here)。

    您可以直接覆盖 setValue:forKey: 以检查需要转换的一个或多个键,并进行适当的更改。

    - (void)setValue:(id)value forKey:(NSString *)key
    {
        if([key isEqualToString:@"someDate"]) {
            NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
            someDate = [dateFormatter dateFromString:value];
            value = somedate;
        }
    
        [super setValue:value forKey:key];
    }
    

    这是从内存中提取的,因此无法保证它是否会真正编译和运行。 ;-)

    【讨论】:

    • 谢谢保罗。这绝对是一种可能。从性能的角度来看,我可能需要量化字符串比较的性能损失。另一个问题是……有时,程序的其他部分可能会尝试在该字段上设置真正的 NSDate ……在这种情况下,我还必须检查类类型。感谢您的建议。
    • 如果有可能传入正确的类型,那么我建议 Pawel 的答案。我认为字符串比较的性能足够好,尤其是在解析 XML 的上下文中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2011-10-18
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多