Swift中的AnyObject和Any

时间:2014-09-12 13:13:22

标签: swift value-type reference-type

我不知道何时使用AnyObject以及何时在Swift中使用Any。

就我而言,我是一本词典

  

[String:???]

??? :可以是Int,Double,Float,String,Array,Dictionary

有人可以解释一下Any和AnyObject之间的区别 以及在我的情况下使用哪一个。

奥洛克

4 个答案:

答案 0 :(得分:104)

AnyObject仅适用于引用类型(类),Any适用于值和引用类型。

所以你应该去[String: Any]

  

为Any和AnyObject输入类型

     

Swift提供了两种特殊类型来处理非特定类型:

     
      
  • Any可以表示任何类型的实例,包括函数   类型。
  •   
  • AnyObject可以表示任何类类型的实例。
  •   
     

注意:

     

仅当您明确需要此行为时才使用AnyAnyObject   他们提供的能力。具体而言总是更好   您期望在代码中使用的类型。

来自 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现已导入Any,而不再是AnyObject

答案 1 :(得分:42)

您使用Any还是AnyObject取决于您的预期用途:

如果您的字典仅在Swift代码中使用,那么您应该使用Any因为您的类型(IntDoubleFloatStringArrayDictionary)不是对象。

如果您要将字典传递给期望NSDictionary的Objective-C例程,那么您应该使用AnyObject

当您import Foundationimport UIKitimport Cocoa时,可以将您的数组声明为[String: AnyObject],但在这种情况下,Swift正在处理您的IntDoubleFloat文字为NSNumberStringNSStringArrayNSArray,以及字典为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)
    }
}