我有一个混合的Obj-C - Swift应用程序
我的自定义Obj-C MapViewController
有以下头文件,其中Item
是用Swift编写的自定义类:
@class Item;
@interface MapViewController : UIViewController
@property (nonatomic, strong) Item *item;
@end
MapViewController
的segue是使用Item
对象item
启动的
self.performSegueWithIdentifier(kMapSegueId, sender: item)
此次调用,其中item
作为sender
发送:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == kMapSegueId {
let mapViewController = segue.destinationViewController as! MapViewController
mapViewController.item = sender as! Item! // This gives the error
}
}
但是,对item
的属性MapViewController
的赋值会给编译器错误
无法指定类型'项目的值!'输入'项目!'
如何避免这种奇怪的错误?
答案 0 :(得分:4)
删除额外的!
。您应该转换为Item
,而不是Item!
。
mapViewController.item = sender as! Item
编译器试图在这里创建太多的隐式桥接器;这是一座太过分的桥梁。即使我打赌.item
的类型是Item!
,您也应该忽略它,并始终将其视为Item
。 Swift 2.2中的!
类型具有很多复杂性(并且应尽可能避免)与许多神奇的ObjC桥接相关联。这就是他们在Swift 3中重新设计的原因。
以上是真的,但可能不是你的问题。问题是sender
本身是可选的。所以你试图从AnyObject?
投射到Item
。您需要先使用sender
或if let
解包!
。
mapViewController.item = sender! as! Item
我可能会把它重写为:
if let item = sender as? Item,
mapViewController = segue.destinationViewController as? MapViewController
where segue.identifier == kMapSegueId {
mapViewController.item = item
}
答案 1 :(得分:1)
由于 vadian 和 Rob Napier 建议,由于项目背后的感叹号,我的代码错误。
但是,删除它确实会产生另一个编译错误。原因如下:
当我开始将现有的Obj-C项目翻译成Swift时,我设置了Bridging标头,并导入了所有的h文件,因为我的所有类都是用Obj-C编写的。然后我开始逐类翻译到Swift
我忘了删除已经转换为Swift的文件的#import语句。因此,类Item
和ViewController
仍有导入语句。
一旦从桥接头删除了这些import语句,编译器错误就消失了。