【问题标题】:AnyObject and Any in SwiftSwift 中的 AnyObject 和 Any
【发布时间】:2014-11-06 16:26:05
【问题描述】:

我不明白在 Swift 中何时使用 AnyObject 以及何时使用 Any

就我而言,我有一个Dictionary

[字符串:???]

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

谁能解释一下AnyAnyObject之间的区别 以及在我的情况下使用哪一个。

【问题讨论】:

    标签: swift value-type reference-type


    【解决方案1】:

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

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

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

    当您 import Foundationimport UIKitimport Cocoa 时,可以将您的数组声明为 [String: AnyObject],但在这种情况下,Swift 会将您的 IntDoubleFloat 文字视为NSNumber,您的Strings 为NSString,您的Arrays 为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 ids 现在被导入为 Any,而不是 AnyObject

      【讨论】:

      • 请注意,StringArrayDictionary 不是类,对于这些使用 Any。
      • Nor Int、Double 和 Float 都是。
      • 是的,但这通常是显而易见的。 NSStringNSArrayNSDictionary 是类并不是很明显,但功能相似的 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)
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多