简体   繁体   中英

Swift 4 Copy an array of objects by value which have array inside

I'm trying to understand how the copy() function works in Swift 4. I have two classes which are structured like this:

class Project {
    var id: Int
    var name: String
    var team: [Person]?

    init(id: Int, name: String, team: [Person]?) {
        self.id = id
        self.name = name
        self.team = team
    }
}

class Person {
    var id: Int
    var name: String
    var project: Project?

    init(id: Int, name: String, project: Project?) {
        self.id = id
        self.name = name
        self.project = project
    }
}

In my program I have an array of projects and what I'm trying to do is to create a copy of the values in the array the following way:

// arrProjects is some array of projects.
let projectsCopy = arrProjects.map { $0.copy() } as! [Project]

For this to work, I've implemented the NSCopying protocol to both classes the following way:

extension Project: NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        let teamCopy = self.team?.map { $0.copy() } as! [Person]?
        return Project(id: self.id, name: self.name, team: teamCopy)
    }
}

extension Person: NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        let projectCopy = self.project?.copy() as! Project?
        return Person(id: self.id, name: self.name, project: projectCopy)
    }
}

However, when I run the code and the arrProjects.map { $0.copy() } runs, the app freezes as if it was cycling and a Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffee5a61ff8) error is thrown at the let teamCopy = self.team?.map { $0.copy() } as! [Person]? let teamCopy = self.team?.map { $0.copy() } as! [Person]? line.

Any idea where I'm going wrong?

You should't use copy() inside the definition of public func copy(with zone: NSZone? = nil) -> Any { You are creating an infinite loop.

extension Project: NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        let copy = Project(id: self.id, name: self.name, team: self.team)
        return copy
    }
}

extension Person: NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        let copy = Person(id: self.id, name: self.name, project: self.project)
        return copy
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM