要创建类实例的“deep”副本,您需要符合这些相关类的nscoping,
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)")
输出:
车站(名称:“宾夕法尼亚站”)
车站(名称:“宾夕法尼亚站”)
<StackOverflow.DepartureViewModel:0x149dc4de0>
<StackOverflow.DepartureViewModel:0x149dc4de0>
<StackOverflow.DepartureViewModel:0x149da89a0>
<停止视图模型的子离开实例:<StackOverflow.Departure View Model:0x149dc4de0>
<SVM子出发实例副本:<StackOverflow.DepartureViewModel:0x149dc7630>