在Swift中将Any转换为AnyObject

时间:2014-11-10 11:29:20

标签: swift

我有一个包含在字典中的对象,如下所示:

let dict:<String, Any> = ["obj": self]

然后,我试图将该对象用作按下按钮的目标:

button.addTarget(dict["obj"], action: "buttonPress:", forControlEvents: .TouchUpInside)

我收到错误:

Type '(String, Any)' does not conform to protocol 'AnyObject'

我在猜这里我的问题是尝试将Any投射为AnyObject。这甚至可能吗?

3 个答案:

答案 0 :(得分:3)

不能从AnyAnyObject进行向下转换,是的,您遇到的问题是Any无法转换为AnyObject

Any可以表示任何类型(类,结构,枚举,整数,字符串等),而AnyObject只能表示引用类型(即类)。

要解决此问题,我认为您应该更改字典以存储AnyObject类型的值:

let dict:<String, AnyObject> = ["obj": self]

请注意,即使字典包含AnyObject值,它也可以存储:

  • 字符串
  • 阵列
  • 字典

因为这些类型会自动桥接到相应的objc类型(NSNumberNSArrayNSDictionary等。)

如果您确实需要具有最大的灵活性,那么我建议您使用NSDictionary - 但在这种情况下,必须在引用类型中显式标记值类型(即int中的NSNumber等)。

另外@ rintaro的回答是另一个好的选择。

答案 1 :(得分:3)

AnyAnyObject是可能的。您可以使用Any的{​​{1}}将AnyObject展开到.unsafelyUnwrapped,无论其类别,结构,枚举,整数,字符串等等。

此处Any返回_change[.oldKey],解包并将其投放到Any,如下面的代码所示。

AnyObject

我已使用KVO override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard let oldKey = (_change[.oldKey].unsafelyUnwrapped as AnyObject).cgPointValue else {                 return             } guard let newKey = (_change[.newKey].unsafelyUnwrapped as AnyObject).cgPointValue else {                 return             } print(oldKey) print(newKey) } extension NSKeyValueChangeKey {     public static let newKey: NSKeyValueChangeKey     public static let oldKey: NSKeyValueChangeKey } 接收ObserveValue forKeyPath格式的更改 我成功检索到从[NSKeyValueChangeKey : Any]转换为CGPoint然后转换为Any的{​​{1}}值。

答案 2 :(得分:2)

您无法将Any投射到AnyObject,但可以将其投射到任何具体类:

    button.addTarget(dict["obj"] as UIViewController, action: "buttonPress:", forControlEvents: .TouchUpInside)

当然,如果dict["obj"]不是UIViewController,这可能会导致运行时错误,因此请更安全:

    if let target = dict["obj"] as? UIViewController {
        button.addTarget(target, action: "buttonPress:", forControlEvents: .TouchUpInside)
    }
    else {
        fatalError("dict[\"obj\"] is not UIViewController!")
    }

当然,最好使用自己的子类,而不是UIViewController