user_
user_

Reputation: 902

How to use self in lazy initialization in Swift

Some websites recommend to initialize views using lazy initialization instead of using a storyboard.

It works when self is not used in lazy initialization. But when self is used in it, a compile error occurs.

For example, in the following code, label1 can be compiled successfully, but label2 can't, because self is used in it.

How to use self in lazy initializations?

class A {
    private let label1: UILabel = {
        return UILabel()
    }()

    private let label2: UILabel = {
        let view = UILabel()
        self.addTextToLabel(view) // compile error !!!
        return view
    }()

    private func addTextToLabel(label: UILabel) {
        label.text = "test"
    }
}

Upvotes: 2

Views: 937

Answers (1)

rmaddy
rmaddy

Reputation: 318794

Your question is written under the misunderstanding that you are currently using lazy initialization. But you are not. Both label1 and label2 are not using lazy initialization. They are being initialized immediately when A is being initialized and this is the cause of the error since self isn't ready when these property initializers are called.

The solution is to actually make label2 a lazy property.

private lazy var label2: UILabel = {
    let view = UILabel()
    self.addTextToLabel(label: view)
    return view
}()

But note that this label2 initialization will not happen until the first time you actually try to access the label2 property.

As per the docs:

A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.

Lazy properties are useful when the initial value for a property is dependent on outside factors whose values are not known until after an instance’s initialization is complete.

Reference: https://docs.swift.org/swift-book/LanguageGuide/Properties.html

Upvotes: 6

Related Questions