Swift中如何深拷贝Array中的对象

我们在开发中会经常使用到数组,在OC中数组可以copy或者mutableCopy,但是在Swift中数组就不能直接拷贝了,为什么呢?大家可以看到下面一张图片,发现它是struct,那么怎么进行copy,下面小编给大家介绍一下吧。


Swift中Array是结构体

没有copy的 情况

首先,创建Person类:

class Person : NSObject {
    var name: String?
    var age: Int?
}

创建两个person,并赋值给self.personArray

    var personArray: Array!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let person1 = Person()
        person1.name = "ZhangFei"
        person1.age = 25
        
        let person2 = Person()
        person2.name = "GuanYu"
        person2.age = 18
        
        let persons = [person1,person2]
        // 赋值给self.personArray
        self.personArray = persons
        // 修改第一个对象的name
        self.personArray[0].name = "LiuBei"
        print(persons[0].name)
   
    }

下张图片是运行后的结果,大家会发现persons的第一个对象的name被修改了。


打印结果是LiuBei

copy后的情况

这里介绍三种方法

第一种:NSCopying

要想对Person进行copy,首先要遵守NSCopying协议和实现copyWithZone方法

class Person : NSObject, NSCopying {
    var name: String?
    var age: Int?
    
    func copyWithZone(zone: NSZone) -> AnyObject {
        let person = Person()
        person.name = self.name
        person.age = self.age
        return person
    }
}

利用map对数组中每个对象进行copy

    var personArray: Array!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let person1 = Person()
        person1.name = "ZhangFei"
        person1.age = 25
        
        let person2 = Person()
        person2.name = "GuanYu"
        person2.age = 18
        
        let persons = [person1,person2]

        // 深拷贝
        self.personArray =  persons.map{($0.copy() as! Person) }
        // 修改第一个对象的name
        self.personArray[0].name = "LiuBei"
        print(persons[0].name)
   
    }

下张为运行后的结果,大家会发现persons的第一个对象的name没有被改变

打印结果是ZhangFei
第二种:自定义copy协议

第一种需要继承NSObject,这种是纯swift写法

protocol Copyable {
    func copy() -> Copyable
}

class Person: Copyable {
    var name: String?
    var age: Int?
    func copy() -> Copyable {
        let p = Person()
        p.name = name
        p.age = age
        return p
    }
}

使用和第一种一样

第三种:使用Struct

在swift中的结构体和oc不同,oc中只能加实例变量,swift中不仅能加实例变量还能加方法

struct Person3 {
    var name: String?
    var age: Int?
}

使用

   var person1 = Person3()
        person1.name = "ZhangFei"
        person1.age = 25
        
        var person2 = Person3()
        person2.name = "GuanYu"
        person2.age = 18
        let persons = [person1,person2]
        
        var personArray: [Person3] =  persons
        // 修改第一个对象的name
        personArray[0].name = "LiuBei"
        print(persons[0].name)

以上三种方法能可以实现copy,在swift中如果不需要继承最好使用结构体。

你可能感兴趣的:(Swift中如何深拷贝Array中的对象)