Ishaan Sejwal
Ishaan Sejwal

Reputation: 690

How to get a mutable copy of a class in swift?

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?

Upvotes: 3

Views: 6734

Answers (3)

wm.p1us
wm.p1us

Reputation: 2069

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

Upvotes: 3

Dallas Johnson
Dallas Johnson

Reputation: 1536

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.

Upvotes: 2

Luca Angeletti
Luca Angeletti

Reputation: 59536

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"

Upvotes: 0

Related Questions