为什么我可以成功将Swift数组结构转换为AnyObject?

时间:2019-11-27 21:31:55

标签: swift

据我所知,Swift对象应符合AnyObjectAny,而结构应仅符合Any

//Tested with Swift 5.0

class Car {
    var name = ""
}

let myArray = [Car]()

let example1 = myArray as? AnyObject
let example2 = myArray as AnyObject

print(example1 != nil) //true
print(example2 != nil) //true

为什么两个例子都是true
据我所知example1应该是nilexample2甚至不能编译。

我的误解在哪里?

3 个答案:

答案 0 :(得分:3)

由于Objective-C的桥接,您可以在Apple平台上将Array<_>强制转换为AnyObject

Apple平台上的Swift编译器和运行时可以将任何Swift类型转换为某种引用对象。通常,将值类型转换为__SwiftValue的实例(该实例是NSObject的子类)。但是,Swift标准库使用一些未记录的语言功能来自定义某些转换:

  • Array<_>投射到NSArray
  • Dictionary<_, _>强制转换为NSDictionary
  • String强制转换为NSString
  • 将数字或布尔值强制转换为NSNumber

答案 1 :(得分:0)

据我所知,

执行此代码后,

let example1 = myArray as? AnyObject

您的myArray由具有引用计数的实体包装。 作为myArray结构(其他值类型也是如此),它没有引用计数。此时,该值已移至堆。 再次转换为数组时,将从包装器中获取此值对象。

关于文档信息,

https://developer.apple.com/documentation/swift/array

从数组到NSArray的桥接需要O(1)时间和O(1)空间,如果数组的元素已经是一个类或@objc协议的实例;否则,它会占用O(n)的时间和空间。

因此,语句“将数组<_>强制转换为NSArray”实际上是无效的。 对于值类型,它更复杂。

更合适的称呼为“装箱”和“取消装箱”

答案 2 :(得分:-1)

您正在向下转换,编译不会抱怨,因为car类隐式符合AnyObject协议。

与您进行的let example1: AnyObject = myArray as? AnyObject相同,您可以了解为什么这两个测试为True。