“无法将类型 'String' 的值分配给类型 'AnyObject?'”,Swift 3,Xcode 8 beta 6

Posted

技术标签:

【中文标题】“无法将类型 \'String\' 的值分配给类型 \'AnyObject?\'”,Swift 3,Xcode 8 beta 6【英文标题】:"Cannot assign value of type 'String' to type 'AnyObject?'", Swift 3, Xcode 8 beta 6“无法将类型 'String' 的值分配给类型 'AnyObject?'”,Swift 3,Xcode 8 beta 6 【发布时间】:2016-08-19 18:09:56 【问题描述】:

一段相当简单的代码

var dict: [String: AnyObject] = [:]
dict["key"] = "value"

产生以下编译时错误

Cannot assign value of type 'String' to type 'AnyObject?'

简单的类型检查告诉我StringAnyObject

"value" is AnyObject // returns true

我可以将 AnyObject 更改为 Any 并且一切正常

var dict: [String: Any] = [:]
dict["key"] = "value"

但我想了解为什么会出现错误? String 不再是 AnyObject 了吗?或者这是一个错误?

【问题讨论】:

【参考方案1】:

在 b6 中,String 不再神奇地桥接到 NSString。 String 不是一个类;这是一个结构。您需要手动进行桥接:

dict["key"] = "value" as AnyObject

is 似乎仍在桥接这一事实可能是一个错误,应该报告。

不用说,[String: AnyObject][String: Any] 在您的代码中应该尽可能少地使用。

(确保遵循 Hamish 在下面的 cmets 中提供的链接。)

【讨论】:

感谢您的回答,一切都如我所料。误报类型检查是我问这个问题的唯一原因。 According to Joe Groff, is/as AnyObject 应该总是成功,因为现在一切都连接到AnyObject。我相信这是因为 id 现在桥接到 Swift,因为 AnyAny 现在可以桥接到 AnyObject(很奇怪,我知道)。 是的,看起来 swift 遇到了 AnyObject 类型检查问题***.com/questions/39033194/… 我能问你为什么不应该在代码中使用 [String:AnyObject] 吗? @RobNapier 好的,现在我明白了!好的,谢谢你的澄清! :)【参考方案2】:

我会用一些官方来源来补充@RobNapier's answer。


隐式桥接机制的移除在以下 Swift 进化提案中被接受,将在 Swift 3 中实现

SE-0072: Fully eliminate implicit bridging conversions from Swift

以前,隐式转换可以一些 Swift 本机类型关联的 Objective-C 类型(符合私有协议 _ObjectiveCBridgeable 的 Swift 类型,例如本机 Int , String, )

因此,我们决定做出妥协。我们会要求 桥接的 Objective-C 转换时显式桥接强制转换 键入 to 其关联的 Swift 值类型(例如,NSString -> String), 但不是相反

... [来自 SE-0072]

在 Swift 3 中,这种隐式转换机制将不再可用。

随着去年 Objective-C 泛型的引入,以及 针对 Swift 的 API 导入的所有令人敬畏的改进 3,我认为是时候重新审视一下完成这个了 工作。

...

我建议我们完全消除隐式桥接转换 斯威夫特 3。这意味着一些用户可能不得不介绍 在他们的代码中更明确的转换,但我们会删除另一个特殊的 从 Swift 的类型系统中提取案例,并能够进一步简化 编译器。

...

以前依赖于 Swift 之间的隐式转换的代码 值类型及其相关的桥接 Objective-C 类型现在将 需要通过as 强制转换

最后,the release notes for Xcode 8 beta 6(需要登录)声明此提案现已在 beta 6 中实施:

Xcode 8 beta 6 中的新功能 - Swift 编译器:Swift 语言

...

桥接转换不再是隐式的。可以使用as 强制从 Swift 值类型到其对应对象的转换。 例如:string as NSString。任何 Swift 值也可以是 使用as AnyObject 转换为它的盒装ID 表示。 (SE-0072)

W.r.t.新的 "boxed id" 允许将任何 Swift 值显式转换为 AnyObject,参见例如以下主题:

AnyObject not working in Xcode8 beta6?

【讨论】:

以上是关于“无法将类型 'String' 的值分配给类型 'AnyObject?'”,Swift 3,Xcode 8 beta 6的主要内容,如果未能解决你的问题,请参考以下文章

如何在iOS(Xcode)中的提交按钮内实现分段控制?