Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a variable, but once done, its value is final

Tags:

swift

I have a model object variable in Swift View Controller. The thing I'd like to do is that at initialisation of the VC, i don't have a value for it. But after an async network call I have the parsed model object which is what this variable should hold, but from then on I don't want anything to change the value of the model variable.

Is it possible to do so in Swift? if yes, how?

like image 831
inforeqd Avatar asked Jan 27 '16 05:01

inforeqd


3 Answers

Based on Babul Prabhakar answer, but a bit more clean.

Approach 1:

var test: String? { didSet { test = oldValue ?? test } }

test = "Initial string"
test = "Some other string"
test = "Lets try one last time"

print(test) // "Initial string"

Edit: made it shorter

Approach 2:

let value: String
value = "Initial string"

I guess the second approach is the "built-in" option of Swift to declare a variable once. This is only possible when the variable is assigned right after the declaration though.

like image 103
Eendje Avatar answered Oct 17 '22 09:10

Eendje


What you can do is

private var myPrivateVar:String?;

var publicGetter:String {
    set {
        if myPrivateVar == nil {
            myPrivateVar = newValue;

        }

    }
    get {
        return myPrivateVar!;
    }
}
like image 42
Babul Prabhakar Avatar answered Oct 17 '22 08:10

Babul Prabhakar


I'd personally go with @Eendje or @Babul Prabhakar's approach if myPrivateVar was somehow set to nil the setter could still write twice. I wanted to share another option that is guaranteed to never get set twice (as long as the token is never written to!):

    private var token: dispatch_once_t = 0

    private var setOnce : String?

    var publicGetter: String {

        set (newValue) {
            dispatch_once(&token) {
                self.setOnce = newValue
            }
        }

        get {
            guard let setOnce = setOnce else {
                return ""
            }
            return setOnce
        }
    }

The dispatch_once() function provides a simple and efficient mechanism to run an initializer exactly once, similar to pthread_once(3). Well designed code hides the use of lazy initialization. For exam-ple: example:

source

like image 2
Dan Beaulieu Avatar answered Oct 17 '22 09:10

Dan Beaulieu