【发布时间】:2016-12-15 06:35:51
【问题描述】:
在 Swift 2.3 中,我必须将 UInt64 转换为 AnyObject 和 as!。但它在 Swift 3 中是 as。一旦我在 Swift 2.3 中转换它,它就会崩溃并显示以下消息。
无法将“Swift.UInt64”(0x10dddde88)类型的值转换为“Swift.AnyObject”(0x12129d018)。
请帮助我。谢谢!
【问题讨论】:
在 Swift 2.3 中,我必须将 UInt64 转换为 AnyObject 和 as!。但它在 Swift 3 中是 as。一旦我在 Swift 2.3 中转换它,它就会崩溃并显示以下消息。
无法将“Swift.UInt64”(0x10dddde88)类型的值转换为“Swift.AnyObject”(0x12129d018)。
请帮助我。谢谢!
【问题讨论】:
在转换方面,Swift 3 与 Swift 2.3 有很大不同。例如,如果您在 Xcode 8 操场上运行以下命令(使用最新的 Swift 工具链,在我的例子中是 Xcode 8.2):
import Foundation
import Swift
struct Foo
{
init()
{
}
}
NSStringFromClass(type(of: Foo() as AnyObject))
您会看到,NSStringFromClass(type(of: Foo() as AnyObject)) 将在右侧的检查栏中注册为"_SwiftValue"。
这是因为 Swift 3 允许您使用内部 _SwiftValue 类将 any 构造包装为 AnyObject,然后可以在代码的其他部分中解包。 p>
Swift 2.3 没有这个功能。那就是你犯错的地方。
但您可以将UInt64 转换为NSNumber。如果我没记错的话,这适用于 Swift 2.3 和 3.0。我意识到您可能正在处理泛型类型,并且您可能在编译期间不知道您正在处理的类型是 UInt64 还是其他类型;但无论如何,这种方法都应该有效。您也可以使用 as? 运算符来处理转换错误和异常。
【讨论】:
在 Swift 2 中,只有 Int 和 UInt 可以转换为 AnyObject(隐式或显式)。
当您将Int 或UInt 显式转换为AnyObject 时,您使用as 转换,而不是as!:
//Swift 2.3
let ui: UInt = 1234
let uiObj = ui as AnyObject
let i: Int = 5678
let iObj = i as AnyObject
其实就是自动转换成NSNumber:
//Swift 2.3
print(uiObj.dynamicType) //->__NSCFNumber (__NSCFNumber is one of the concrete subclasses of NSNumber)
print(iObj.dynamicType) //->__NSCFNumber
在 Swift 3 中,一些隐式转换被移除,但从 3.0.1 开始,所有整数类型都可以通过显式转换转换为 NSNumber:
//Swift 3.0.2
let ui64: UInt64 = 12345678
let ui64Obj = ui64 as AnyObject
let i8: Int8 = 123
let i8Obj = i8 as AnyObject
let ui: UInt = 1234
let uiObj = ui as AnyObject
let i: Int = 5678
let iObj = i as AnyObject
print(type(of: ui64Obj)) //->_SwiftTypePreservingNSNumber (_SwiftTypePreservingNSNumber is another subclass of NSNumber)
print(type(of: i8Obj)) //->_SwiftTypePreservingNSNumber
print(type(of: uiObj)) //->_SwiftTypePreservingNSNumber
print(type(of: iObj)) //->_SwiftTypePreservingNSNumber
因此,如果您想在 Swift 2 中获得与 Swift 3 中的 uint64Value as AnyObject 几乎相同的结果,则需要显式构造 NSNumber。
//Swift 2.3
let ui64: UInt64 = 12345678
let ui64Obj = NSNumber(unsignedLongLong: ui64)
print(ui64Obj.dynamicType) //->__NSCFNumber
将uint64Value as AnyObject 替换为NSNumber(unsignedLongLong: uint64Value)。
(其实_SwiftTypePreservingNSNumber和__NSCFNumber并不完全一样,但这可能不是你的问题。)
顺便说一句,当我在 Xcode 8.2 中将 Legacy Swift 标志设置为 YES 时,它显示了一个警告:
Swift 2.3 已弃用,将在未来版本中删除 Xcode。立即迁移到 Swift 3。
Apple 强烈鼓励我们立即迁移到 Swift 3。
你最好快点把你的代码迁移到 Swift 3。
【讨论】: