Swift: "Cannot assign value of type 'Item!' to type 'Item!"
Swift: "Cannot assign value of type 'Item!' to type 'Item!"
我有一个混合的 Obj-C - Swift 应用程序。
我的自定义 Obj-C MapViewController
具有以下头文件,其中 Item
是用 Swift 编写的自定义 class:
@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
}
}
但是,对 MapViewController
的 属性 item
的赋值给出了编译器错误
无法将类型 'Item!' 的值分配给类型 'Item!'
如何避免这个奇怪的错误?
删除多余的 !
。您应该转换为 Item
,而不是 Item!
。
mapViewController.item = sender as! Item
编译器试图在这里建立太多的隐式桥接;这是一座桥太远了。尽管我打赌 .item
的类型是 Item!
,但您应该忽略它并始终将其设为 Item
。 Swift 2.2 中的 !
类型在它们周围有很多复杂性(并且应该尽可能避免)与许多神奇的 ObjC 桥接相关。这就是它们在 Swift 3.
中重新设计的原因
以上是正确的,但可能不是你的问题。问题是 sender
本身是可选的。因此,您正在尝试从 AnyObject?
转换为 Item
。您需要先使用 if let
或 !
.
打开 sender
mapViewController.item = sender! as! Item
我可能会将其重写为:
if let item = sender as? Item,
mapViewController = segue.destinationViewController as? MapViewController
where segue.identifier == kMapSegueId {
mapViewController.item = item
}
正如 vadian 和 Rob Napier 所建议的那样,由于 Item[= 后面的感叹号,我的代码是错误的24=].
但是,删除它确实会产生另一个编译器错误。原因如下:
当我开始将我现有的 Obj-C 项目转换为 Swift 时,我设置了桥接 header,并在那里导入了我所有的 h-files,因为我所有的classes 是在 Obj-C 中编写的。然后我开始将 class 由 class 翻译成 Swift.
我忘记删除文件的 #import 语句,这些文件已经翻译成 Swift。 所以,classes 仍然有导入语句Item
和 ViewController
。
我从桥接 header 中删除这些导入语句后,编译器错误就消失了。
我有一个混合的 Obj-C - Swift 应用程序。
我的自定义 Obj-C MapViewController
具有以下头文件,其中 Item
是用 Swift 编写的自定义 class:
@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
}
}
但是,对 MapViewController
的 属性 item
的赋值给出了编译器错误
无法将类型 'Item!' 的值分配给类型 'Item!'
如何避免这个奇怪的错误?
删除多余的 !
。您应该转换为 Item
,而不是 Item!
。
mapViewController.item = sender as! Item
编译器试图在这里建立太多的隐式桥接;这是一座桥太远了。尽管我打赌 .item
的类型是 Item!
,但您应该忽略它并始终将其设为 Item
。 Swift 2.2 中的 !
类型在它们周围有很多复杂性(并且应该尽可能避免)与许多神奇的 ObjC 桥接相关。这就是它们在 Swift 3.
以上是正确的,但可能不是你的问题。问题是 sender
本身是可选的。因此,您正在尝试从 AnyObject?
转换为 Item
。您需要先使用 if let
或 !
.
sender
mapViewController.item = sender! as! Item
我可能会将其重写为:
if let item = sender as? Item,
mapViewController = segue.destinationViewController as? MapViewController
where segue.identifier == kMapSegueId {
mapViewController.item = item
}
正如 vadian 和 Rob Napier 所建议的那样,由于 Item[= 后面的感叹号,我的代码是错误的24=].
但是,删除它确实会产生另一个编译器错误。原因如下:
当我开始将我现有的 Obj-C 项目转换为 Swift 时,我设置了桥接 header,并在那里导入了我所有的 h-files,因为我所有的classes 是在 Obj-C 中编写的。然后我开始将 class 由 class 翻译成 Swift.
我忘记删除文件的 #import 语句,这些文件已经翻译成 Swift。 所以,classes 仍然有导入语句Item
和 ViewController
。
我从桥接 header 中删除这些导入语句后,编译器错误就消失了。