我不知道何时使用AnyObject以及何时在Swift中使用Any。
就我而言,我是一本词典
[String:???]
??? :可以是Int,Double,Float,String,Array,Dictionary
有人可以解释一下Any和AnyObject之间的区别 以及在我的情况下使用哪一个。
奥洛克
答案 0 :(得分:104)
AnyObject
仅适用于引用类型(类),Any
适用于值和引用类型。
所以你应该去[String: Any]
。
为Any和AnyObject输入类型
Swift提供了两种特殊类型来处理非特定类型:
Any
可以表示任何类型的实例,包括函数 类型。AnyObject
可以表示任何类类型的实例。注意:强>
仅当您明确需要此行为时才使用
Any
和AnyObject
他们提供的能力。具体而言总是更好 您期望在代码中使用的类型。
-
另请注意,当您使用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
现已导入Any
,而不再是AnyObject
。
答案 1 :(得分:42)
您使用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
为NSString
,Array
为NSArray
,以及字典为NSDictionary
,所有这些都是对象。使用AnyObject
作为值类型的字典可转换为NSDictionary
,但使用Any
的字典不可转换为。{/ p>
答案 2 :(得分:0)
泛型是类型安全的,这意味着如果你将字符串作为泛型传递并尝试使用整数,编译器会抱怨并且你将无法编译你的(这很好)。 (这是因为Swift使用静态类型,并且能够给你编译错误)
如果使用AnyObject,编译器不知道这个对象可以被视为String还是Integer,并且基本上允许你用它做任何你想做的事情(这很糟糕)就像你试图使用一个对象一样当它是一个Integer时,它已作为String传递,应用程序将崩溃。 (这是因为Swift使用动态类型,只会给你一个运行时错误)
答案 3 :(得分:0)
默认情况下我们应该使用“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)。< /p>
import UIKit
class CustomType {
func customMethod(arg1: AnyObject) {
let tableView = UITableView()
let numberOfRows = arg1.tableView(tableView, numberOfRowsInSection: 0)
}
}