3

I get an unexpected result when I append a new object onto an array of objects. The append seems to overwrite the existing object in the array then append itself.

Any thoughts? Or am I missing something really simple.

Here's test code from my playground:

class myRecord {

    var firstName: String?
    var lastName: String?
     }

var myRecords = [myRecord]() 
var tempRecord = myRecord()


tempRecord.firstName = "John" 
tempRecord.lastName = "Brown" 
myRecords.append(tempRecord)

tempRecord.firstName = "Jane" 
tempRecord.lastName = "Doe" 
myRecords.append(tempRecord)

for x in 0..<myRecords.count {
    print(x, "=", myRecords[x].firstName!, myRecords[x].lastName!) }

Console output: 
0 = Jane Doe
1 = Jane Doe
EdDry
  • 141
  • 1
  • 6
  • 1
    yes because you kept changing the value of the same object which is `tempRecord` – Lamour Aug 16 '17 at 22:52
  • what @Lamar said. The array has an address to that object in memory. If you update the bytes of that object, the array still has the same address in to that object, what's at that address though has changed. – mdo123 Aug 16 '17 at 22:57
  • 1
    Have you solved your problem? – Jaydeep Vora Aug 18 '17 at 06:22
  • Yes, changing from declaring a class to a struct gave me the results I expected. Copying the values into the array rather than passing them through as a reference made all the difference. Thanks for the enlightenment! – EdDry Aug 20 '17 at 20:05

4 Answers4

1

This happens obviously because class are Reference Type. if your creating object of class that means your are creating memory reference of that class. And if you are changes property of that class that means your are changing the value of that reference in your memory heap. That why your last object (i.e Jane Doe) is replacing the value value of first Object(i.e John Brown).

So now in Array both elements refers same memory reference that why you getting both same object(i.e Jon Doe). If you changes implementation to struct, you getting answer as per you are implementing, Because struct are Value Type. So it refers only value of object.

To be more specify About class and struct Please read this link

Jaydeep Vora
  • 6,085
  • 1
  • 22
  • 40
1

Just replace 'class' with 'struct' as class are reference type and struct are value type.

struct myRecord {

    var firstName: String?
    var lastName: String?
}

var myRecords = [myRecord]()
var tempRecord = myRecord()


tempRecord.firstName = "John"
tempRecord.lastName = "Brown"
myRecords.append(tempRecord)

tempRecord.firstName = "Jane"
tempRecord.lastName = "Doe"
myRecords.append(tempRecord)

for x in 0..<myRecords.count {
    print(x, "=", myRecords[x].firstName!, myRecords[x].lastName!) }
Dev
  • 112
  • 1
  • 7
  • I did try this. But I keep getting this error "Editor placeholder in source file". struct Step { let id = UUID() var count: Int var date: Date } var stepCount = [Step]() var tempStepCount = Step(count: Int>, date: Date) – grooot Jan 20 '21 at 04:19
0

When you re-assigned the value of tempRecord.firstName and tempRecord.lastName, it overwrote the value at index 0 of the myRecords array to equal the new values you set.

Index 0 and Index 1 of the myRecords array both point to the same tempRecord class instance in memory which holds the value

{ firstName: Jane, lastName: Doe }

In order to add multiple instances of the myRecord class, you could create a separate instance called tempRecords1 and append the values to the myRecords array like so:

...

var tempRecord = myRecord()
var tempRecord1 = myRecord()

...

tempRecord1.firstName = "Jane"
tempRecord1.lastName = "Doe"
myRecords.append(tempRecord1)
knoble
  • 25
  • 5
0

just put after

tempRecord.firstName = "John" 
tempRecord.lastName = "Brown" 
myRecords.append(tempRecord)

tempRecord = myRecords ()

then add jane doe.

you can use Struct instead of Class, depends on what you need.

NiTrOs
  • 359
  • 2
  • 7