Inout 参数没有相同的地址

Inout parameters don't have the same address

我有三个 类 A、B 和 C。A 有一个名为 rA 的资源。我想要实现的是所有这些实例都引用了完全相同的资源。

所以具体来说 Swift 术语:

Class A 有一个 属性 叫做 foo:

private var foo : [Bar] = [Bar]() // shared resource

Class B 有一个名为 foo 的 属性 作为 inout 参数传递给初始化程序:

private var foo : [Bar]!
init(inout foo:[Bar]){
    self.foo = foo
}

Class C 类似于 Class B

如果我将 foo 从 Class A 传递到 Class B(或 C),地址会发生什么变化?

在 A 中,我会像这样将它传递给 B(或 C):

let b = B(foo: &self.foo)

当我在 A 中初始化 foo 后打印地址时,它给我的地址与 B 中赋值后的地址不同。

class A{
    private var foo = [Bar]()
    func someFunc(){
        NSLog("\n\n [A] \(unsafeAddressOf(self.foo))\n\n") // different from output in B
        let b = B(foo: &self.foo)

    }
}

class B{
    private var foo: [Bar]!
    init(inout foo: [Bar]){
         self.foo = foo
         NSLog("\n\n [B] \(unsafeAddressOf(self.foo))\n\n")
    }
}

知道为什么会这样吗?

Swift数组是值类型,因此在

self.foo = foo

您将 foo 分配给 self.foo。现在这是两个独立的数组 (即使实际元素仅在其中一个数组发生变异时才被复制)。

此外,您不能使用 unsafeAddressOf() 获取 Swift 数组的地址,因为 该函数采用 AnyObject 参数,该参数是 class 的一个实例,即 值类型。在

 unsafeAddressOf(self.foo)

Swift 编译器实际上将 Swift 数组桥接到 NSArray。如图所示 在 , 当重复完成时,这可能会或可能不会导致相同的对象。任何状况之下, 打印的地址是不是Swift数组的存储位置。

如果您需要一个可以传递的真实引用,那么您可以将数组包装在 class 中。 使用 NS(Mutable)Array 也可能是一种选择,但这样您会失去许多 Swift 功能。