如何在swift中获取类的可变副本?

时间:2015-12-02 12:28:14

标签: swift

swift语言指南解释了swift中的类是如何引用类型和结构是值的,即当创建结构的实例时,它被复制到新的标识中而不是对它的引用,而是一个新的实例。从另一个类实例创建的类仅仅是对同一个类的引用。 (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID88

  

结构和枚举是值类型

     

值类型是一种类型,其值在分配给a时被复制   变量或常量,或传递给函数时。

...

  

类是引用类型

     

与值类型不同,引用类型不会被复制   分配给变量或常量,或者当它们被传递给a时   功能。而不是副本,对同一存在的引用   而是使用实例。

有没有办法创建一个可以独立于它继承的类使用的类的可变副本?

3 个答案:

答案 0 :(得分:2)

以与Objective-C类似的方式,您需要使您的类符合NSCopying协议并在该类上实现public func copyWithZone(zone: NSZone) -> AnyObject。然后根据需要对属性进行深层复制。

但也许问题更多的是你是否应该使用Class而是使用Struct,这样你就可以获得免费的价值语义。

答案 1 :(得分:1)

阅读关于模式的书我发现了这种解决方案:

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

答案 2 :(得分:0)

您可以像这样定义Clonable协议

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

接下来,当某个类符合Clonable时,它有责任实施clone方法。

class Sheep:Clonable {
    var name: String

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

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

接下来,您可以创建Sheep

let dolly = Sheep(name: "Dolly")

克隆它

let cloned = dolly.clone()

现在dollycloned是对2个不同实例的引用

cloned.name = "Cloned"
dolly.name // "Dolly"
cloned.name // "Cloned"