Глубокая копия структуры - как? - PullRequest
0 голосов
/ 26 августа 2018

У меня есть следующая структура, из которой я хочу сделать глубокую копию, так что я могу относиться к ней по-разному.

class NearbyStopsViewModel {
    var stopViewModels: [StopViewModel]
}

class StopViewModel {
    var stop: Stop
    var name: String
    var departures: [DepartureViewModel]?
}

class DepartureViewModel: NSObject {
    var departure: Departure
    var name: String
}

Я с трудом оборачиваюсь, делая глубокую копию этогоструктура, есть идеи?

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Вы можете воспользоваться типами значений, которые по умолчанию глубоко копируются, предостережение в том, что все члены также являются типами значений (структуры, перечисления, кортежи), и эти члены содержат только типы значений и т. Д.

struct NearbyStopsViewModel {
    var stopViewModels: [StopViewModel]
}

struct StopViewModel {
    var stop: Stop
    var name: String
    var departures: [DepartureViewModel]?
}

struct DepartureViewModel: NSObject {
    var departure: Departure
    var name: String
}

struct Departure {
    // fields needed for the struct
}

При такой иерархии каждое присвоение любому из вышеперечисленных типов приведет к глубокой копии всех базовых элементов. Вы позволяете компилятору делать всю работу за вас.

Остерегайтесь, однако, могут возникнуть некоторые проблемы с производительностью, если вы работаете с большим количеством этих значений (для достаточной суммы производительность не заметна).

0 голосов
/ 26 августа 2018

Чтобы создать «глубокую» копию экземпляра класса, вам необходимо соответствовать NSCopying для этих соответствующих классов, Structs передаются по значению.Я добавил свою собственную реализацию для отсутствующих структур.

import Foundation

struct Departure {
    var to: Stop
    var from: Stop

    init(from: Stop, to: Stop) {
        self.from = from
        self.to = to
    }
}

struct Stop {
    var name: String = ""

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

class NearbyStopsViewModel: NSCopying {
    var stopViewModels: [StopViewModel]

    init(stops: [StopViewModel] = []) {
        self.stopViewModels = stops
    }

    func copy(with zone: NSZone? = nil) -> Any {

        var stops: [StopViewModel] = []
        self.stopViewModels.forEach { (stop) in
            stops.append(stop.copy() as! StopViewModel)
        }

        let nearbysvm = NearbyStopsViewModel.init(stops: stops)
        return nearbysvm

    }
}

class StopViewModel: NSCopying {

    var stop: Stop
    var name: String = ""
    var departures: [DepartureViewModel]

    init(stop: Stop, named: String, with departures: [DepartureViewModel] = [] ) {
        self.stop = stop
        self.name = named
        self.departures = departures
    }

    func copy(with zone: NSZone? = nil) -> Any {

        var departuresCopy: [DepartureViewModel] = []
        self.departures.forEach { (departure) in
            departuresCopy.append(departure.copy() as! DepartureViewModel)
        }

        let stopvm = StopViewModel.init(stop: self.stop, named: self.name, with: departuresCopy)
        return stopvm
    }
}


class DepartureViewModel: NSObject, NSCopying {

    var departure: Departure
    var name: String = ""

    init(name: String, departure: Departure) {
        self.name = name
        self.departure = departure
    }

    func copy(with zone: NSZone? = nil) -> Any {
        let departure = DepartureViewModel.init(name: self.name, departure: self.departure)
        return departure
    }
}


// Structs are passed by Value, making a 'minimal' copy of themselves as they move.
var pennStation = Stop(named: "Pennsylvania Station")
print(pennStation)
let copyByValue = pennStation
print(copyByValue) // "Pennsylvania Station"
pennStation.name = "Penn. Station"
print(copyByValue) // "Pennsylvania Station"

// Classes are passed by Reference
let clarkLake = Stop(named: "Clark and Lake")
let stateLake = Stop(named: "State and Lake")

let clarkToState = Departure(from: clarkLake, to: stateLake)

// DepartureViewModel is your lowest level class that conforms to NSCopying
let departure = DepartureViewModel(name: "clark to state", departure: clarkToState)
print(departure) // This Memory Address should never change.
let referenceDeparture = departure
departure.name = "Unexpected delay"
print(referenceDeparture.name)
print(referenceDeparture) // Same Address as departure.

let deepCopyOfDeparture = departure.copy() as! DepartureViewModel // Copy() and mutableCopy() will return a passed-by-value copy.
print(deepCopyOfDeparture) // Different Memory Address as departure


let stopvm = StopViewModel(stop: pennStation, named: "Penn. Station", with: [departure])
print("Stop View Model's Child Departure Instance(s): \(stopvm.departures)")
let copyOfSVM = stopvm.copy() as! StopViewModel
print("Copy of SVM Child Departure Instance(s): \(copyOfSVM.departures)")

Вывод:

Стоп (имя: "Станция Пенсильвания")

Стоп (имя: "Станция Пенсильвания ")

Остановка (название:" Станция Пенсильвания ")

Неожиданная задержка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...