Swift 如何在调用setValueForKey之前验证类型

Swift 如何在调用setValueForKey之前验证类型,swift,Swift,我想使用setValueForKey从字典中设置对象属性。如果字典中有错误的数据(例如:数据是String,但属性是Double),setValueForKey函数将崩溃 为了停止此崩溃,我添加了如下类型比较: if type(of: propertyValue) == type(of: dataValue) { // Data is the correct type setValue(dataValue, forKey: property) } 这里的问题是,如果数据具有1

我想使用setValueForKey从字典中设置对象属性。如果字典中有错误的数据(例如:数据是
String
,但属性是
Double
),setValueForKey函数将崩溃

为了停止此崩溃,我添加了如下类型比较:

if type(of: propertyValue) == type(of: dataValue) {
    // Data is the correct type
    setValue(dataValue, forKey: property)
} 
这里的问题是,如果数据具有
1
,则类型为
Int
,并且即使setValueForKey在这里工作正常,也不会写入
Double
type属性

如何检查数据类型是否可以强制转换为属性类型而不会在setValueForKey上崩溃

编辑

我的车祸正好相反。当属性为
String
时,尝试使用
Double
调用setValueForKey时,我遇到以下问题:

由于未捕获异常“NSInvalidArgumentException”而终止应用程序,原因:'-[\uu NSCFNumber length]:发送到实例的选择器无法识别

我应该在原来的帖子中详细说明这一点,但这是我的计划

我正在制作一个可以用字典初始化的超级类。init方法应该在超类中,并且应该设置所有子类属性

class DictionaryClass: NSObject {
    init?(_ data: [String: Any]) {
        super.init()

        let mirror = Mirror(reflecting: self)
        // Loop over properties
        for arg in mirror.children {
            // If data has no value for property return nil
            // If data has wrong type of value for property return nil
            // Else do setValueForKey
        }
    }
}
目标是:

class Example: DictionaryClass {
    var someNumber: Double = 0
    var coolString: String = ""
}

let data: [String: Any] = ["someNumber": 2, "coolString": "Example"]
let example = Example(data) 

print(example.coolString) // "Example"

let data2: [String: Any] = ["someNumber": 2, "coolString": 4]
let example2 = Example(data2) // nil

let data3: [String: Any] = ["someNumber": 2]
let example3 = Example(data3) // nil

还有一点,但这是最基本的想法,如果有更快捷的方法,我会洗耳恭听。

问题是斯威夫特的打字是静态的,而不是动态的。您不能强制转换为
类型(of:dataValue)
;您必须显式地说出类型的名称才能强制转换它。因此,您必须在编译时知道类型是什么。如果您知道这一点,那么就可以使用
as?
安全地进行测试

此外,正如您正确指出的,没有必要进行任何明确的强制转换。这是因为
setValue:forKey:
和KVC是Objective-C,所以所有这些都通过Objective-C和NSNumber传递

另一方面,我无法重现报道的坠机事件。在我的测试中,通过
setValue:forKey:
传递一个字符串,其中预期会有一个Double,但不会崩溃;它只给出零:

class C2 : NSObject {
    @objc var dataValue : Double = 2
    func test() {
        self.setValue("howdy", forKey: "dataValue")
    }
}
let c2 = C2()
c2.test()
print(c2.dataValue) // 0.0

更广泛地说,我想问你为什么要使用KVC。您没有显示任何上下文,但我敢打赌,有一种更好、更快捷的方法来执行您尝试执行的任何操作。

如果您执行类型比较,然后尝试将类型
Int
的值设置为类型
Double
的键,这实际上是不对的,是吗?那你为什么要将
Int
设置为
Double
类型呢?@nayem我没有在帖子中指定,但是传入的数据是来自JSON的,所以以
[String:Any]
的形式传入,但是当
Any
1
类型(of:)返回
Int
“如果有更快捷的方法,我洗耳恭听”斯威夫特真的根本不适合做这种事情。正如你们已经发现的,镜子只带你们走这么远;内省是有限的,类型(正如我在回答中所说)是静态的。如果你需要这么灵活的东西,为什么不用字典呢?(或者编一本字典。)基本上你是想把斯威夫特变成一门完全不同的语言。也许你应该用Objective-C写这门课@马特:好的,谢谢你的帮助,我不认为我在Objective-C方面有足够的技能来创建这个,所以我会让这个项目休息一会儿。我真的不明白,如果我不能检查它是否会崩溃,为什么setValueForKey在Swift中可用。它不是Swift的一部分。这是一个Objto-C可可基金会的特点。谢谢你的答复,你是正确的崩溃不工作,我用错误的方式描述它。我编辑了我的问题,以便有更多的背景。如果你能看一下,我会非常感激的!