所有这些都是关于包装任何对象或类型(= Any)并且能够检查类型是否在以后相等。使用类作为类型和值的包装可以正常工作。我的问题是我想抛出一个对象,通过反射找到它的属性,并为每个具有该属性的(包装)类型的属性创建一个包装器。问题是反射的属性总是类型为Any - 我需要转换为它们的实际类型(例如String)。
示例将清除:
// Functions to check equality of Types
func unsafeGetTypeId(type: Any.Type) -> uintptr_t {
return unsafeBitCast(type, uintptr_t.self)
}
func areOfSameType(v1: Any, v2: Any) -> Bool {
return unsafeGetTypeId(reflect(v1).valueType) == unsafeGetTypeId(reflect(v2).valueType)
}
class ZType {
}
class ZTypeT<T> {
var value: Any?
init() {
}
init( value: T ) {
self.value = value
}
}
class SampleClass {
var sampleProperty : String
init( aString: String ) {
self.sampleProperty = aString
}
}
var sample = SampleClass(aString: "Hans")
var t1 = ZTypeT<String>()
var t2 = ZTypeT(value: sample.sampleProperty)
areOfSameType(t1, t2) // true
var mirror = reflect(sample)
for var index=0; index<mirror.count; ++index {
let (propertyName, childMirror) = mirror[index]
var tTestAgainst = ZTypeT<String>()
// This is obviously of type Any so it won`t be ZTypeT<String>() but ZTypeT<Any>()
var tMirrorProp = ZTypeT(value: childMirror.value)
areOfSameType(tMirrorProp, tTestAgainst) // false
// So how could i cast the value back to it`s type? This would work but it should be generic : i don`t know the type beforehand
var tMirrorPropCasted = ZTypeT(value: childMirror.value as String)
areOfSameType(tMirrorPropCasted, tTestAgainst) // false
}
正如您所看到的那样,直到tMirrorProp才能正常工作,因为它不是String类型。如果我施展它,我的支票将再次成立 - 但我不能在不知道类型的情况下施放。有没有人知道解决这个问题的解决方案。使用Swift-Classes的解决方案是首选,但与NSObject一起使用的解决方案仍然是有趣的。
答案 0 :(得分:0)
正如您已经说过的,实例化正确类型的唯一方法是将childMirror.value强制转换为正确的类型。你可以通过为每种类型添加一个开关来做到这一点。然后使用NSStringFromClass(tMirrorPropCasted.dynamicType)
比较对象。你会得到类似的东西:
var tMirrorPropCasted : ZTypeT<Any>
var theValue = anyValue
let mi:MirrorType = reflect(theValue)
if mi.disposition == .Optional {
if mi.count == 0 { // Optional.None
theValue = NSNull()
} else {
let (name,some) = mi[0]
theValue = some.value
}
}
switch(theValue) {
case let intValue as Int:
tMirrorPropCasted = ZTypeT(value: childMirror.value as Int)
case let doubleValue as Double:
tMirrorPropCasted = ZTypeT(value: childMirror.value as Double)
case let stringValue as String:
tMirrorPropCasted = ZTypeT(value: childMirror.value as String)
case let boolValue as Bool:
tMirrorPropCasted = ZTypeT(value: childMirror.value as Bool)
case let anyvalue as NSObject:
tMirrorPropCasted = ZTypeT(value: childMirror.value as NSObject)
default:
tMirrorPropCasted = ZTypeT(value: childMirror.value)
}
但是,您还可以检查值属性的类型,而不是检查对象的类型。该属性仍将包含其原始类型的信息。所以你能做的就是测试
if NSStringFromClass(tTestAgainst.value.dynamicType) == NSStringFromClass(tMirrorProp.value.dynamicType) {
NSLog("Same type")
}