无法将“Swift.UInt64”(0x10dddde88)类型的值转换为“Swift.AnyObject”(0x12129d018)

Posted

技术标签:

【中文标题】无法将“Swift.UInt64”(0x10dddde88)类型的值转换为“Swift.AnyObject”(0x12129d018)【英文标题】:Could not cast value of type 'Swift.UInt64' (0x10dddde88) to 'Swift.AnyObject' (0x12129d018) 【发布时间】:2016-12-15 06:35:51 【问题描述】:

在 Swift 2.3 中,我必须将 UInt64 转换为 AnyObjectas!。但它在 Swift 3 中是 as。一旦我在 Swift 2.3 中转换它,它就会崩溃并显示以下消息。

请帮助我。谢谢!

【问题讨论】:

【参考方案1】:

在转换方面,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? 运算符来处理转换错误和异常。

【讨论】:

【参考方案2】:

在 Swift 2 中,只有 IntUInt 可以转换为 AnyObject(隐式或显式)。

当您将IntUInt 显式转换为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。

【讨论】:

以上是关于无法将“Swift.UInt64”(0x10dddde88)类型的值转换为“Swift.AnyObject”(0x12129d018)的主要内容,如果未能解决你的问题,请参考以下文章

无法将“UIView”(0x10d54a4c0)类型的值转换为“UIButton”(0x10d552120)

Swift 2.0:无法将类型“__NSArrayM”(0x10a9348d8)的值转换为“NSDictionary”(0x10a934d60)

为啥添加到 esp 是 0x10?

十进制的0x10是啥?

按日期对 Firebase 数据进行排序

详解UDS CAN诊断:DiagnosticSessionControl Service(SID:0X10)