0

Here is my code:

    var productsList:[Product]

    switch category {
    case 0:
        productsList = self.sharedInstance.productsList1
    case 1:
        productsList = self.sharedInstance.productsList2
    default:
        productsList = self.sharedInstance.productsList3
    }

    for productDic in products {
        let product = Product()
        // Set product attributes here.
        productsList.append(product)
    }

    println(productsList)
    println(self.sharedInstance.productsList1)
    println(self.sharedInstance.productsList2)
    println(self.sharedInstance.productsList3)

The output:

  • productsList contains some added content
  • productsList1, productsList2 and productsList3 are all empty.

In my understanding, productsList should refer to one of productsList1, productsList2 and productsList3 depending on the category.

Can someone explain why productsList1, productsList2 and productsList3 are all empty?

Thanks in advance.

1
  • 2
    Array is value type so it copy on assignment. The behaviour you expected is for reference type. Commented Aug 17, 2015 at 2:10

1 Answer 1

3

Assigning the array from sharedInstance results in the array being copied.

You would need to re-assign the updated array to the sharedInstance array after making the update.

As a minimal example:

var list:[String] = []

list.append("String1")
list.append("String2")
list.append("String3")

var list2:[String] = list

list2.append("String4")

println(list)
println(list2)

Will result in the output:

"[String1, String2, String3]" "[String1, String2, String3, String4]"

You would need to add a re-assignment to get the lists matching:

//...
list2.append("String4")
list = list2
println(list)
println(list2)

You can also demonstrate the copy by printing the address of each list after assignment and showing they are different.

print(unsafeAddressOf(list))
print(unsafeAddressOf(list2))

Or you can check in the debugger.

If you want to operate specifically on the sharedInstance copies of your arrays you could do one of the following:

  • Instead of 3 separate properties, you could put them in a parent array property and select an index in your switch statement, rather than a new variable
  • Wrap your arrays in a custom class, instances of which are passed by reference.

You could also use NSMutableArray, although it's probably not the best of ideas to mix the old and new like that.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for answering. Is there a way to explicitly force the variable to take the same reference? I think it is annoying to assign it back, and make the code not concise.
Thanks Tom for the recommendations! I think I will use the parent array option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.