代码之家  ›  专栏  ›  技术社区  ›  Recusiwe

结构的深度复制-如何?

  •  0
  • Recusiwe  · 技术社区  · 6 年前

    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 回复  |  直到 6 年前
        1
  •  0
  •   RLoniello    6 年前

    要创建类实例的“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>

        2
  •  0
  •   Cristik    6 年前

    您可以利用默认情况下被深度复制的值类型,这里需要注意的是,所有成员也是值类型(结构、枚举、元组),并且这些成员只包含值类型,依此类推:

    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
    }
    

    不过,请注意,如果使用大量这些值(对于足够多的值来说,性能问题是不明显的),则可能会出现一些性能问题。