Manngo
Manngo

Reputation: 16281

Initializer in a Swift Class

I have come to Swift from other languages. There is a pattern I sometimes use in defining a class in which the initializer calls another function which would be called later to re-initialize.

class Test {
    var thing: String
    init() {
        reinit()    //  'self' used in method call 'load' before all stored properties are initialized
    }               //  Return from initializer without initializing all stored properties
    func renit() {
        self.thing = "Hello"
    }
}

In this case, it doesn’t work. I really don’t want to write the initializing code twice, and I can’t use test.init(), apparently to re-intialize.

What is the correct way of doing this?

Update

A few comments suggest that this is a bad design, and it may well be. In reality, of course, the application will not be so trivial.

The point is that I can do it this way in other languages, so I’m wondering what is the correct approach in Swift.

Upvotes: 1

Views: 500

Answers (2)

Rob Napier
Rob Napier

Reputation: 299265

If your object can be "re-initialized" then just initialize it to some base-state by default:

class Test {
    var thing: String = "" // Add default value
    init() {
        reinit()
    }          

    func reinit() {
        self.thing = "Hello"
    }
}

As a rule, I think this is probably a bad design. Instead of "reinitializing," replace this class with a struct, and just throw it away and replace it when you want to reset things. As a rule, structs are very cheap to create. But if you need this, then default values is ok.

Upvotes: 3

Alexander
Alexander

Reputation: 63147

One way is to make thing into an implicitly unwrapped optional. This sound dangerous, but it's really just a regression to what almost every other language does (e.g. Java, Ruby, Python, JS, where all object references behave like IUOs).

Alternatively, you duplicate the assignments. If the values are complex, you can extract, like so:

class Test {
    var thing: String
    init() {
        self.thing = generateThing()
    }

    func renit() {
        self.thing = generateThing()
    }

    func generateThing() -> String { "Hello" }
}

Upvotes: 2

Related Questions