3

The swift language guide explains how classes in swift are reference types and structs are value i.e. when an instance of a struct is created, it is copied into the new identity instead of a reference to it, whereas, a new instance of a class created from another instance of a class are mere reference to the same class. (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID88)

Structures and Enumerations Are Value Types

A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function.

...

Classes Are Reference Types

Unlike value types, reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used instead.

Is there a way to create a mutable copy of a class that can be use independent of the class it inherited from?

Ishaan Sejwal
  • 660
  • 9
  • 29
  • A natural approach would be to use a standard [NSCopying](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/) protocol, you can also implement deep copying at your own methods. – A-Live Dec 02 '15 at 12:30
  • 2
    Why not write an `init` that takes another object of the same type, and set the new object's variables from the original's? – BallpointBen Dec 02 '15 at 12:34
  • You need to be more explicit. What class exactly are you talking about? Because if you are just worrying about the built-in Array and Dictionary structs, don't be: just write `var mutArray = array` and modify mutArray as you wish. – Gwendal Roué Dec 02 '15 at 12:36
  • Take a look at http://stackoverflow.com/questions/24242629/implementing-copy-in-swift – Rik Dec 02 '15 at 12:37
  • Related: http://stackoverflow.com/questions/25645090/protocol-func-returning-self. – Martin R Dec 02 '15 at 12:37
  • 1
    For clarification purposes, I believe when you say you want '*to create a mutable copy of a class that can be use independent of the class it inherited from*' what you actually mean is '*to create a mutable copy of an instance of a class that can be used independent of the original instance it was copied from*', don't you? If so, please consider editing your question ;) – veducm Dec 02 '15 at 12:39

3 Answers3

3

Reading book about patterns I found this kind of solution:

protocol Copying {
    init(instance: Self)
}

extension Copying {
    func copy() -> Self {
        return Self.init(instance: self)
    }
}


class Person: Copying {
    var name: String!
    var surname: String!
    init() {}
    required init(instance: Person) {
        self.name = instance.name
        self.surname = instance.surname
    }
}

let p1 = Person()
let p2 = p1.copy()
p1.name = "P1"
p2.name = "P2"
print(p1.name) // P1
print(p2.name) // P2
print(p1.name) // P1
wm.p1us
  • 2,019
  • 2
  • 27
  • 38
2

In a similar fashion to Objective-C you would need to make your class conform to NSCopying protocol and implement public func copyWithZone(zone: NSZone) -> AnyObject on that class. Then do a deep copy of properties as needed.

But perhaps the question is more whether you should be using a Class and instead use a Struct so you get the value semantics you are looking for free.

Dallas Johnson
  • 1,546
  • 10
  • 13
0

You could define a Clonable protocol like this

protocol Clonable {
    typealias Element
    func clone() -> Element
}

Next, when a class does conform to Clonable it has the responsibility to implement the clone method.

class Sheep:Clonable {
    var name: String

    init(name: String) {
        self.name = name
    }

    func clone() -> Sheep {
        return Sheep(name: self.name)
    }
}

Next you can create a Sheep

let dolly = Sheep(name: "Dolly")

an clone it

let cloned = dolly.clone()

Now dolly and cloned are references to 2 different instances

cloned.name = "Cloned"
dolly.name // "Dolly"
cloned.name // "Cloned"
Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
  • the problem with this is, my class will have to depend on that init function and i have a lot of properties that will need to be copied using this technique. – Ishaan Sejwal Dec 02 '15 at 15:14
  • One question: if you want the exact same behaviour of a `Struct`... then why don't you use a `Struct`? – Luca Angeletti Dec 02 '15 at 15:33
  • because it is an core data created NSMangedObject subclass that I have been expansively using through out the project, but only now I need this new functionality. See my more specific question: http://stackoverflow.com/questions/34046661/getting-a-copy-of-an-instance-of-nsmanagedobject-class-in-swift – Ishaan Sejwal Dec 02 '15 at 15:37