self is used before all properties are initialized (Swift)

struct ModelDemo {

    let callback : () -> ()

}



final class ViewModelDemo {

    let modelDemo: ModelDemo

    init() {

        modelDemo = ModelDemo(callback: self.modelCallback)

    }

    

    private func modelCallback() {

    }

}

The above generates the error "'self' used before all stored properties are initialized."

I understand the error, but this is a common programming pattern for me in other languages. Is there a preferred way to do something like this in Swift?

My current workaround is to make the callback property of ModelDemo into an optional and initialize it to nil, then to set it from the ViewModelDemo init() after it (and other ViewModel properties) have been initialized.

FWIW, the intent of the code is to give the Model a way to inform the ViewModel that something in the Model has changed. Since the Model is supposed to be isolated from the View, I don't think I should use @ObservableObject as that's a SwiftUI feature.

How about this:

struct ModelDemo {
    var callback: () -> () = {}
}

final class ViewModelDemo {
    var modelDemo = ModelDemo()

    init() {
        modelDemo.callback = modelCallback
    }

    private func modelCallback() {
    }
}

You need to declare the callback in ModelDemo(). Otherwise you get error :

Missing argument for parameter 'callback' in call
Insert 'callback: <#() -> ()#>'

This should work (or at least compile):

typealias CallBack = () -> ()

struct ModelDemo {
    var callback : CallBack? // () -> ()
}

final class ViewModelDemo {

    var modelDemo = ModelDemo(callback: nil)

    init() {
        modelDemo.callback = modelCallback
    }

    private func modelCallback() {

    }

}

I like it as it gets rid of the optional.
However, but that still requires that the property 'callback' in ModelDemo and the property 'modelDemo' need to be var's.
If there was a way to do everything in the init(), they could be let's

You could protect the vars by making them "private (set)" (which, as you probably know, makes them read-only to the outside world (as if they were "let")).

Giving this:

struct ModelDemo {
    private (set) var callback: () -> () = {}
    
    mutating func setCallback(_ callback: @escaping () -> ()) {
        self.callback = callback
    }
}



final class ViewModelDemo {
    private (set) var modelDemo = ModelDemo()

    init() {
        modelDemo.setCallback(modelCallback)
    }

    private func modelCallback() {
    }
}

private (set) helps. Thanks.

self is used before all properties are initialized (Swift)
 
 
Q