在 Swift 3 中,Objective-C 中的 id 类型现在映射为 Swift 中的 Any ,它描述了一个任意类型的值,无论是类、枚举、结构体还是其他 Swift 类型。这个变化致使 Objective-C API 在 Swift 中更加灵活,因为 Swift 中定义的值类型可以传送到 Objective-C API 中并作为 Swift 类型展开,消除了手动“包装”类型的需求。这些好处同时扩展了集合:Objective-C 集合类型 NSArray 、 NSDictionary 以及 NSSet ,它先前只接受 AnyObject ,现在可以包含 Any 类型。对于哈希容器,比如 Dictionary 和 Set ,现在有新的类型 AnyHashable 能保存任何遵循 Swift 中Hashable 协议的类型。总的来说,从 Swift 2 到 Swift 3 的类型映射改动如下表:
Objective-C | Swift 2 | Swift 3 |
---|---|---|
id | AnyObject | Any |
NSArray * | [AnyObject] | [Any] |
NSDictionary * | [NSObject: AnyObject] | [AnyHashable: Any] |
NSSet * | Set<NSObject> | Set<AnyHashable> |
很多情况下,你的代码就不会受到这个改变的影响。Swift 2 中隐式转换为 AnyObject 的代码在 Swift 3 中还是会照常作为Any运作。总之,还是有一些地方比如你声明的变量和方法需要改变并在 Swift 3 中获得最好的体验。同时,从 Swift 3 开始,在对象和值类型不能再隐式转换,如果你的代码显式地使用 AnyObject 或者 Cocoa 类比如NSString 、 NSArray 或者 NSDictionary ,你就得引入更多显式地使用 as NSString 或者 as String 转换。Xcode 中的自动迁移工具在你从 Swift 2 迁移到 Swift 3 时将做最小的改动来保证你的代码可编译,但结果可能不能总是完美。这篇文章将描述一些你需要做的改动,以及一些获得 id 作为 Any 优势时需要规避的陷阱。