【问题标题】:How to know the type of the object boxed in NSValue with Swift?如何使用 Swift 知道 NSValue 中装箱的对象的类型?
【发布时间】:2014-12-22 15:14:29
【问题描述】:

我有一个 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},我认为这就是它永远不会出现在子句中的原因。

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

非常感谢!

【问题讨论】:

  • 在 NS* 和 CG* 之间有一个免费的桥接。您是否尝试在 if 子句中使用 NSPoint 而不是 CGPoint ?例如。 if value is NSPoint {
  • 我试过了,但是编译器不接受这种比较并且我得到一个错误'Use of undeclared type NSPoint'

标签: ios swift nsvalue


【解决方案1】:

啊,NSValue,你太疯狂了。尽管 NSRect 等不应该在 iOS 上出现,但如果你将 CGRect 放在 NSValue 中,它在内部会显示它里面有一个 NSRect

无论如何,尽管它们的用途相似,但我认为您不能使用AnyNSValue 转换为CGPointCGRect 或从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(甚至更好,泛型)代替?

【讨论】:

  • 这很好,但我想模拟 CAKeyFrameAnimation 的行为,它具有 [AnyObject] 类型的属性“值”!但无论如何,感谢您的解决方案。那会奏效的。
【解决方案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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多