Search code examples
arraysswiftswift-nio

Property does not persist in array?


My goal is to persist a swift-nio Scheduled instance in a struct named Receiver in an array to potentially use later. It creates the Receiver, stores it in the array and adds the Scheduled instance, but the Receiver instance in the array does not contain the Scheduled instance.

What could be causing this and how could I fix it?

It does not occur with anything else and the task associated with the Scheduled instance still executes. The XCode debugger even shows the instance in the Receiver associated with a variable, yet not in the array.

    private var receivers: Array<Receiver>

    func connect() {
        var entry = Receiver(
            // ...
            )
        receivers.append(entry)
        connect(&entry)
    }

    func connect(_ device: inout Receiver) {
        startTimeout(&device)
        // device contains timeout, but receivers[0] does not
    }

    private func startTimeout(_ entry: inout Receiver) {
        stopTimeout(&entry) // Does nothing initially (timeout not yet set)
        
        var device = entry
        // The timeout is added once here
        entry.timeout = entry.eventLoop.scheduleTask(in: .seconds(10), {
            print("Receiver timeout occurred")
            self.reconnect(&device)
            return 0
        })
    }

    func someStuff() {


        // This does not work. timeout is nil, the timeout still occurs
        stopTimeout(&entry) // Cancels the Scheduled timeout
    }
struct Receiver {
    var timeout: Scheduled<Any>?
}

Solution

  • Your struct Receiver is a value type. Everytime it is passed it gets copied (a new instance is created). Manipulating it will alter only the new instance. You avoided that by using inout parameters.

    But with:

    receivers.append(entry)
    

    you are appending a new instance to the array. Modifing entry later on will not affect the instance in the array.

    In this case you should use a class.

    class Receiver {
        var timeout: Scheduled<Any>?
    }