Swift 中的 AnyObject 和 Any
Posted
技术标签:
【中文标题】Swift 中的 AnyObject 和 Any【英文标题】:AnyObject and Any in Swift 【发布时间】:2014-11-06 16:26:05 【问题描述】:我不明白在 Swift 中何时使用 AnyObject
以及何时使用 Any
。
就我而言,我有一个Dictionary
[字符串:???]
??? : 可以是Int
, Double
, Float
, String
, Array
, Dictionary
谁能解释一下Any
和AnyObject
之间的区别
以及在我的情况下使用哪一个。
【问题讨论】:
【参考方案1】:您使用Any
还是AnyObject
取决于您的预期用途:
如果您的字典仅在 Swift 代码中使用,那么您应该使用 Any
,因为您的类型(Int
、Double
、Float
、String
、Array
和 Dictionary
)不是对象。
如果您要将字典传递给期望 NSDictionary
的 Objective-C 例程,那么您应该使用 AnyObject
。
当您 import Foundation
或 import UIKit
或 import Cocoa
时,可以将您的数组声明为 [String: AnyObject]
,但在这种情况下,Swift 会将您的 Int
、Double
、Float
文字视为NSNumber
,您的String
s 为NSString
,您的Array
s 为NSArray
,您的字典为NSDictionary
,所有这些都是对象。使用AnyObject
作为值类型的字典可以转换为NSDictionary
,但使用Any
的字典则不能。
【讨论】:
【参考方案2】:AnyObject
仅用于引用类型(类),Any
用于值和引用类型。
所以你应该去[String: Any]
。
Any 和 AnyObject 的类型转换
Swift 提供了两种特殊类型来处理非特定类型:
Any
可以表示任何类型的实例,包括函数 类型。AnyObject
可以表示任何类类型的实例。注意:
仅当您明确需要该行为和 他们提供的能力。最好具体一点 您希望在代码中使用的类型。
来自 Swift 编程语言: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html#//apple_ref/doc/uid/TP40014097-CH22-ID342
-
还请注意,当您使用 Cocoa API 时,通常会收到一个 AnyObject 数组,这是因为 Objective-C 数组不是典型的。 所以你需要将它们转换为你期望的数组类型。
-
编辑:(2015 年 12 月 22 日) 在最后一条语句中,请注意这在 Swift 2.0 和 Xcode 7 中发生了变化。 Apple 在 Objective-C 中引入了‘Lightweight’ generics,因此许多 Cocoa API 现在已经返回正确的类型。
编辑:(2016 年 10 月 18 日)
请注意,从 Swift 3.0 开始,Objective-C id
s 现在被导入为 Any
,而不是 AnyObject
。
【讨论】:
请注意,String
、Array
和 Dictionary
不是类,对于这些使用 Any。
Nor Int、Double 和 Float 都是。
是的,但这通常是显而易见的。 NSString
、NSArray
和 NSDictionary
是类并不是很明显,但功能相似的 Swift 版本不是类,这让许多开发人员感到困惑。
Any 是否也代表选项?还是应该表示为 Any?
@robdashnash Any 不代表可选项。 ?应添加以使其成为可选【参考方案3】:
Check this SO answer:
泛型是类型安全的,这意味着如果您将字符串作为泛型传递并尝试将其用作整数,编译器会报错并且您将无法编译您的(这很好)。 (发生这种情况是因为 Swift 使用的是静态类型,并且能够给你一个编译器错误)。 如果你使用 AnyObject,编译器不知道这个对象是可以被视为字符串还是整数,并且基本上允许你对它做任何你想做的事情(这很糟糕),就好像你尝试使用一个已经被当它是一个整数时作为字符串传递,应用程序将崩溃。 (这是因为 Swift 使用的是动态类型,只会给你一个运行时错误)
【讨论】:
【参考方案4】:根据 Apple 的 Swift 文档,
Any 可以表示任何类型的实例,包括函数 类型和可选类型。 AnyObject 可以表示任何类类型的实例。更多详情请查看:Blog
【讨论】:
【参考方案5】:默认情况下,我们应该使用“Any”,如果我们需要更高的精度,那么我们可以选择更多受约束的类型,例如 AnyHashable、AnyObject、AnyClass、CustomType 等。
在将对象打磨到用 Objective-C 编写的框架(如 UIKit 和 Foundation)时,应使用 AnyObject。
AnyObject 接受类类型的实例,但不接受枚举、结构和可选类类型对象的实例:
class CustomType
var instanceArg1: Int
var instanceArg2: String
static var classArg1: Int
AnyObject 类型的特殊性在于该类型的对象可以通过自动完成访问所有@objc 方法和变量。如果导入 UIKit 或 Foundation,则 AnyObject 实例对象可以通过自动完成访问所有 Foundation 对象的所有变量和方法。
下面的代码首先在运行时编译但应用程序崩溃,因为给定的参数是 String 类型而不是 UITableView 并且没有在 String 类型中定义的方法 tableView(_:numberOfRowsInSection)。
import UIKit
class CustomType
func customMethod(arg1: AnyObject)
let tableView = UITableView()
let numberOfRows = arg1.tableView(tableView, numberOfRowsInSection: 0)
【讨论】:
以上是关于Swift 中的 AnyObject 和 Any的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中的错误:(键:AnyObject,值:AnyObject)' 不能转换为 'NSDictionary'
swift中Any,AnyObject,AnyClass的区别
为啥在 Swift 中的铸造成本如此之高,而不是……将其保留为 AnyObject?
将“var touch:AnyObject?= touches.anyObject()”转换为 Swift 1.2 [重复]