2

我有一个 NSValue 对象,它可以“装箱”一个未知类型(CGPoint、CGRect 等)的实例,我需要在运行时确定这种类型。我将如何在 Swift 中做到这一点?

我试图做这样的事情:

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

value是一个包含 CGPoint 的 NSValue 对象时,它不会进入 if 子句。然后我在打印value时给了我NSPoint: {150, 150},我认为这就是为什么它永远不会出现在子句中。

任何想法为什么会发生这种情况以及如何解决它?

非常感谢!

4

2 回答 2

4

啊,,NSValue你太疯狂了。即使NSRectetc 不应该是 iOS 上的东西,如果你把 aCGRect放在里面NSValue,它在内部会显示它NSRect里面有一个。

无论如何,虽然它们具有相似的目的,但我认为您不能用它Any来将 a 转换NSValueCGPointor CGRect。你必须打电话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(甚至更好的泛型)来代替?

于 2014-12-22T16:38:02.913 回答
2

首先,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
}
于 2014-12-22T16:39:19.790 回答