Reputation: 690
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
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
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
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