简体   繁体   中英

Computed property not updating with mutating function values

I seem to have a very perplexing Swift problem.

I have a struct called "Graph" which has a number of mutating functions that change its stored properties. The struct's initializer reads from a text file and saves the data in various stored properties.

struct Graph {

    var dists: [[Int]]
    .
    .
    .

    func tourValue() -> Int {
        return dists.count
    }

    mutating func swapHeuristic() {
        dists = [[0], [1]]
    }

    mutating func twoOpt() {
        dists = [[1]]
    }
    .
    .
    .
}

I also have a function makeFile() which creates a text file for the graph to read from.

The main issues lie with my ContentView.swift file, where I create and use instances of Graph.

ContentView.swift

import SwiftUI

struct ContentView: View {
    var nodes: Int
    var graph: Graph { // Graph object is initialized and stored perfectly

        set {
            makeFile(nodes: nodes, selection: .Euclidean) // this works perfectly 
        }
        get {
            Graph(flag: -1, filename: "\(nodes)nodesEUCLIDEAN.txt") // this works perfectly
        }

    }

    var originalTour: Double {
        graph.tourValue() // saves the original tour value perfectly
    }



    var swapValue: Double {
        
        set {
            graph.swapHeuristic() // does not change Graph's dists property like it should

        }

        
        get {
            return graph.tourValue() // as a result of dists not changing, the tourValue is also unchanged
        }

    }

    var body: some View {
        Text("Hello, World!")

    }

}


Thus, the initialized graph instance never has its property changed, and I can't derive values from it.

How do I solve this?

Your graph variable is computed, so unless its mutated form is reflected somewhere else (other objects/properties, a file, etc) the mutation is inevitably lost.

When you set swapValue = 0 , first the getter for var graph is called, creating a new Graph instance. Then that instance executes swapHeuristic() . Since that function mutates the value, it triggers the setter for var graph . The serious red flag here is that your setter ignores newValue . newValue in the setter is at that point the only piece of your code which has the mutated form of your graph. But it does nothing with that value, so when the setter finishes it's simply deallocated.

The question is already answered, but in attempt to be helpful, let me come at the same point from a slightly different direction.

The line

var graph: Graph { // Graph object is initialized and stored perfectly

is a form of self delusion. There is no Graph object that is initialized and stored. This is, as you've been told, a computed property. So consider it in full:

var graph: Graph { // Graph object is initialized and stored perfectly

    set {
        makeFile(nodes: nodes, selection: .Euclidean) // this works perfectly 
    }
    get {
        Graph(flag: -1, filename: "\(nodes)nodesEUCLIDEAN.txt") // this works perfectly
    }
}

What we see in the get part (the getter) is not the retrieval of a stored Graph. It is the creation of a new graph. Every single time we ask for graph , a completely new and different Graph is created at that moment and passed out to the caller.

Thus there is no existing object to mutate. The line graph.swapHeuristic() causes a completely new Graph to come into existence, calls the method, and throws that Graph away.

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