the_critic
the_critic

Reputation: 12820

Inout parameters don't have the same address

I have three classes A, B and C. A has a resource called rA. What I am trying to achieve is that all of those instances have a reference to the exact same resource.

So to concrete in Swift terms:

Class A has a property called foo:

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

Class B has a property called foo which is passed into the initializer as an inout parameter:

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

Class C is analogous to Class B

How come, if I pass foo from Class A to Class B (or C) the address changes ?

In A I would pass it to B (or C) like so:

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

When I print the address after initialization of foo in A it gives me a different address than after assignment in 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")
    }
}

Any ideas why this is the case ?

Upvotes: 2

Views: 101

Answers (1)

Martin R
Martin R

Reputation: 539685

Swift arrays are value types, therefore in

self.foo = foo

you assign the value of foo to self.foo. This are two independent arrays now (even if the actual elements are copied only when one of the arrays is mutated).

Also you cannot take the address of a Swift array with unsafeAddressOf() because that function takes an AnyObject parameter which is an instance of a class, i.e. a value type. In

 unsafeAddressOf(self.foo)

the Swift compiler actually bridges the Swift array to an NSArray. As demonstrated in Swift, Strings and Memory Addresses, this may or may not result in the same object when done repeatedly. In any case, the printed address is not the storage location of the Swift array.

If you need a real reference which you can pass around then you can wrap the array in a class. Using NS(Mutable)Array might also be an option, but then you lose many Swift features.

Upvotes: 3

Related Questions