如何制作一个快速的类对象数组的深层副本

时间:2015-12-24 02:06:16

标签: ios swift

所以我知道swift数组是作为struct实现的,它会自动自动复制。

我已经写了我的课程MyClass,我已经实施了copyWithZone来复制它

但是,我的swift数组包含我的MyClass个对象,例如:

var array = [MyClass]()

当我想复制那个数组时,如

var anotherArray = array

它仍然不会调用MyClassObject.copyWithZone,之后如果我更改array中的对象属性,anotherArray也会反映更改。

如何在没有编写for循环来迭代每个对象的情况下制作的副本?

它没有像View here to see demo那样重复,因为我不能用struct来重写我的类。

3 个答案:

答案 0 :(得分:7)

作为一个简单的陈述,你可以使用这样的代码:

var copiedArray = array.map{$0.copy()}

请注意,术语“deepCopy”对于您所谈论的内容有点误导。如果数组是异构的并且包含其他容器(如数组,字典,集合以及其他自定义容器和“叶子”对象),该怎么办?你应该做的是创建一个DeepCopiable协议,并要求任何符合DeepCopiable的对象都要求任何子对象也符合DeepCopiable协议,并编写deepCopy()方法以递归方式调用所有对象的deepCopy()儿童对象。这样你最终可以使用任意深度的深拷贝。

答案 1 :(得分:1)

感谢Duncan提供的解决方案,这是使用它的扩展程序。 请注意,您的类必须采用NSCopying协议。有关如何操作,请参阅此处https://www.hackingwithswift.com/example-code/system/how-to-copy-objects-in-swift-using-copy

extension Array {
    func copiedElements() -> Array<Element> {
        return self.map{
            let copiable = $0 as! NSCopying
            return copiable.copy() as! Element
        }
    }
}

答案 2 :(得分:0)

如果数组的Element是引用类型,则使该Element与NSCopying一致并实现copyWithZone方法。

class Book {
    var name: String

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

extension Book: NSCopying {
    func copy(with zone: NSZone? = nil) -> Any {
        return Book(name)
    }
}

现在实现数组扩展以进行深层复制

extension Array where Element: NSCopying {
      func copy() -> [Element] {
            return self.map { $0.copy() as! Element }
      }
}

测试代码库

let b1 = Book("Book1")
let b2 = Book("Book2")

let list = [b1, b2]
let clonedList = list.copy()

clonedList现在是list的副本,并且如果您对两者之一进行更改,则不会互相影响。