Swift:"无法指定类型'项目的值!'输入'项目!"

时间:2016-08-18 14:20:03

标签: objective-c swift casting variable-assignment

我有一个混合的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的赋值会给编译器错误

无法指定类型'项目的值!'输入'项目!'

如何避免这种奇怪的错误?

2 个答案:

答案 0 :(得分:4)

删除额外的!。您应该转换为Item,而不是Item!

    mapViewController.item = sender as! Item

编译器试图在这里创建太多的隐式桥接器;这是一座太过分的桥梁。即使我打赌.item的类型是Item!,您也应该忽略它,并始终将其视为Item。 Swift 2.2中的!类型具有很多复杂性(并且应尽可能避免)与许多神奇的ObjC桥接相关联。这就是他们在Swift 3中重新设计的原因。

以上是真的,但可能不是你的问题。问题是sender本身是可选的。所以你试图从AnyObject?投射到Item。您需要先使用senderif 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语句。因此,类ItemViewController仍有导入语句。

一旦从桥接头删除了这些import语句,编译器错误就消失了。