如何知道使用Swift在NSValue中装箱的对象的类型?

时间:2014-12-22 15:14:29

标签: ios swift nsvalue

我有一个NSValue对象可以" box"一个未知类型的实例(CGPoint,CGRect等),我需要在运行时确定这种类型。我怎么能在Swift中做到这一点?

我试着这样做:

if ((value as Any) is CGPoint) {}
else if (((value as Any) is CGRect)) {}
...

value是包含CGPoint的NSValue对象时,它不会进入if子句。 然后,当我打印value时,它给了我NSPoint: {150, 150},我认为这是为什么它永远不会进入该条款。

为什么会发生这种情况以及如何解决这个问题?

非常感谢!

2 个答案:

答案 0 :(得分:3)

啊,NSValue,你这么疯狂。即使NSRect等不应该是iOS上的东西,如果你在CGRect内放置NSValue,在内部显示它内部有NSRect

无论如何,虽然它们用于类似目的,但我认为您不能使用AnyNSValue转换为CGPointCGRect。你必须致电value.CGRectValue()等。但是到了你的观点,你需要知道它是什么。这也不容易,但你可以这样做:

let type = String.fromCString(val.objCType) ?? ""
if type.hasPrefix("{CGRect") {
    let rect = val.CGRectValue()
}
else if type.hasPrefix("{CGPoint") {
    let point = val.CGPointValue()
} //etc...

但另一个问题是,你真的需要使用NSValue吗?这是一种Obj-C特定的解决方法。它是通过你无法改变的东西给你的,或者你可能更好地使用Any(甚至更好的,泛型)?

答案 1 :(得分:1)

首先,iOS不使用NSPoint,因此这将是一种损失。我对这样的事情的最佳猜测是回到使用objCType,这是在Objective-C中处理它的方式。不幸的是,你无法从swift访问@encode,所以你不得不对这些可能性进行硬编码:

switch String(CString: value.objCType, encoding: NSUTF8StringEncoding) {
case "{CGPoint=dd}":  // handle CGPoint here
case "{CGRect={CGPoint=dd}{CGSize=dd}}": // handle CGRect here
}