我有一个包含在字典中的对象,如下所示:
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
。这甚至可能吗?
答案 0 :(得分:3)
不能从Any
向AnyObject
进行向下转换,是的,您遇到的问题是Any
无法转换为AnyObject
。
Any
可以表示任何类型(类,结构,枚举,整数,字符串等),而AnyObject
只能表示引用类型(即类)。
要解决此问题,我认为您应该更改字典以存储AnyObject
类型的值:
let dict:<String, AnyObject> = ["obj": self]
请注意,即使字典包含AnyObject
值,它也可以存储:
因为这些类型会自动桥接到相应的objc类型(NSNumber
,NSArray
,NSDictionary
等。)
如果您确实需要具有最大的灵活性,那么我建议您使用NSDictionary
- 但在这种情况下,必须在引用类型中显式标记值类型(即int
中的NSNumber
等)。
另外@ rintaro的回答是另一个好的选择。
答案 1 :(得分:3)
Any
到AnyObject
是可能的。您可以使用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
。