0

I'm stumped about this one: I have a custom class called CClass. Within this class is a counter called counter. I initialize my instances as follows.

var ArrayEntity = [CClass]()
var ParentOne = CClass()
var ParentTwo = CClass()

Later, I assign each Parent to one of the Array entities, like so:

ParentOne = ArrayEntity[i]
ParentTwo = ArrayEntity[i]

Sometimes i will be the same value for both, and thus both will refer to the same Array instance. The trouble is that if I do something like this:

ParentOne.counter = 1
//value of ParentTwo.counter also becomes 1
//ArrayEntity[i].counter also becomes 1

I wish to have these Parent guys be independent of the ArrayEntity entries they are cloned from, but how do I do this?

Thanks much for any insight. Hopefully it's just a stupid oversight!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
John
  • 33
  • 5
  • Sorry, initial post was not clear enough. Effectively yes: counter (and the class as a whole) is a copy of another instance. – John May 30 '18 at 22:35
  • Use a `struct` instead of `class`. What you are seeing is normal for classes when two variables point to the same reference. – rmaddy May 30 '18 at 22:36
  • As I'm over 2,000 lines deep into the code, and the whole thing depends on this class, might I do something like copy the individual portions of the class over? Like do this instead: ParentOne.counter = ArrayEntry[i].counter? Will that keep things separate or not? – John May 30 '18 at 22:38

1 Answers1

0

That's just how classes work. Assignment does not copy the object; it merely creates multiple references to the same object. Consider:

class Dog {
    var name : String = "Fido"
}
var fido = Dog()
print(fido.name) // Fido
var rover = fido
rover.name = "Rover"
print(fido.name) // Rover

In that code, we changed the name property of rover, a class instance — and the name property of fido was changed as well! That’s because, after the assignment in the third line, fido and rover refer to one and the same instance.

If you don't want that sort of thing to happen, don't maintain two references to one and the same instance. A possible strategy here might be give Dog an init(dog:) method that makes a new Dog that starts out life with the same property values as the original — a clone, as it were. Now you've got two separate objects that can proceed to live independent lives.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Structs, however, do not behave in that way. With a struct, assignment _does_ copy. See my answer here: https://stackoverflow.com/questions/27364117/is-swift-pass-by-value-or-pass-by-reference/27366050#27366050 – matt May 30 '18 at 22:44
  • Wow, thank you! Very informative stuff! It appears if I copy over just the individual parts of the class, I can get away with it, but in future I should definitely be using a struct for this rather than a class. – John May 30 '18 at 22:53
  • You can "get away with it" as long as the parts _themselves_ are not classes. If they are, you'll get the same issue one level down. :) – matt May 30 '18 at 23:00