2

After watching build better apps with value type . In the photoshop example they made, they said that

the only thing that gets copied in the two instances of that diagram are the tiles that contain the person's shirt. So even though I have two distinct documents, the old state and the new state, the only new data that I have had to consume as a result of that is the tiles contained in this person's shirt.

So I begin to wonder how would these two array in memory looks like. So I do a little experiment.

struct Test {
    var i: Int
    var j: Int
}

var valueArray = [Test(i: 1, j: 9), Test(i: 2, j: 7)]
var valueArray2 = valueArray

When I print valueArray and valueArray2's address, they are not the same.
"Maybe they implement this by store pointer in array?"
But when I print memory content using lldb , they are actually just 4 Int (1,9,2,7).
So I am confused, I haven't even change the array yet. And they seems to make a copy of entire array? So where did I misunderstand?
The function I used to print struct's address is by using the method provided by @nschum in this question.

func address(o: UnsafePointer<Void>) {
    let addr = unsafeBitCast(o, Int.self)
    print(NSString(format: "%p", addr))
}

This is not a duplicate question of this question. I am asking about language feather and the other one is about programming skill.

Community
  • 1
  • 1
Nick Allen
  • 1,647
  • 14
  • 20
  • new vars are indeed created, but the internal representation will be same and will be copied on write internally. Devs have no access to the internal implementation details of the value types. – Shripada Apr 08 '16 at 03:39
  • Possible duplicate of [How can I make a container with copy-on-write semantics? (Swift)](http://stackoverflow.com/questions/32984258/how-can-i-make-a-container-with-copy-on-write-semantics-swift) – Vatsal Manot Apr 08 '16 at 04:53
  • This is not a duplicate question of that question. I am asking about language feather and the other one is about programming skill. – Nick Allen Apr 08 '16 at 04:57

2 Answers2

2

Okay, I did many experiment and finally figured out.

  1. We can's use & to get array address because once we do that , Swift will copy the array to better interact with C, use & get object's address that adjacent to array and do the math instead. Or use lldb instruction frame variable -L
  2. The whole Array is copied once any of it's value element changed.
  3. Actual value element of Array is allocated at heap.
  4. Swift also did a lot of optimization for Array whose element is class.
  5. Swift is awesome.

I actually write my first blog for this.

Nick Allen
  • 1,647
  • 14
  • 20
  • It seems to me, that all your tests are done in a playground, which is interpreted as far as I know. So this might change, the way things are stored in memory. – Juangamnik Jul 14 '16 at 15:31
0

After your comments and getting a better understanding if this, I loaded it up in a playground and it seems to be working as expected

enter image description here

original answer for reference

The thing to remember with this is that structs are basically chunks of data in memory. When you create the valueArray, a chunk of memory is being set to value it's assigned

When you create valueArray2, you're creating a new instance of the struct, which means it will have a brand new chunk of memory, and you're then setting the value of that new chunk of memory to the same value of the chunk of memory from the valueArray. This results in a copy of the data in two different memory locations.

This is in contrast to an object, in which case valueArray would be a pointer to a chunk of memory, and when you create valueArray2 it would be creating a new pointer to the same chunk of memory.

GetSwifty
  • 7,568
  • 1
  • 29
  • 46
  • That's something I know of , I expect some optimization like not copying util write. – Nick Allen Apr 08 '16 at 04:21
  • What are you expecting them to optimize? The point of using value types is that copies are not associated with each other in any way. That requires them to be in different locations. – GetSwifty Apr 08 '16 at 04:26
  • `Multiple copies of an array share the same storage as long as none of the copies are modified. ` from [Array Structure Reference](https://developer.apple.com/library/tvos/documentation/Swift/Reference/Swift_Array_Structure/index.html) – Nick Allen Apr 08 '16 at 04:28
  • And according to the WWDC video, only elements in array that changed will be copied. – Nick Allen Apr 08 '16 at 04:35
  • hm...interesting. Wasn't aware of this! I would assume each variable would still have it's own memory address and I'm expecting the debugger will show you it's value regardless. Have you tried printing the memory locations of the structs included in the arrays? – GetSwifty Apr 08 '16 at 04:39
  • Yeah, I tried and no luck. But I found myself so dumb that still using Swift2.2. I am updating Xcode now. It may take me a whole day regard to my school's network condition... I will let you know if this worked. – Nick Allen Apr 08 '16 at 04:42
  • See updated answer. It seems to work as you expected in my playground with the latest versions. Hope that helps. – GetSwifty Apr 08 '16 at 04:50
  • I waste almost half a day trying to figure out this, and it turns out it is only because I forget to update my IDE ! Now I can have a nap... I will accept your answer once I finished my updating and confirm by myself. – Nick Allen Apr 08 '16 at 04:53
  • You should use `&valueType` to pass address instead of pass this object, which will have a different output, problem stay unsolved. – Nick Allen Apr 09 '16 at 02:29